d7d583c6963a0d1b66693290401c2129a62ad7d1
[scpubgit/Object-Remote.git] / lib / Object / Remote / Role / Connector / PerlInterpreter.pm
1 package Object::Remote::Role::Connector::PerlInterpreter;
2
3 use IPC::Open2;
4 use Object::Remote::ModuleSender;
5 use Object::Remote::Handle;
6 use Scalar::Util qw(blessed);
7 use Moo::Role;
8
9 with 'Object::Remote::Role::Connector';
10
11 has module_sender => (is => 'lazy');
12
13 sub _build_module_sender {
14   my ($hook) =
15     grep {blessed($_) && $_->isa('Object::Remote::ModuleLoader::Hook') }
16       @INC;
17   return $hook ? $hook->sender : Object::Remote::ModuleSender->new;
18 }
19
20 around connect => sub {
21   my ($orig, $self) = (shift, shift);
22   my $conn = $self->$orig(@_);
23   Object::Remote::Handle->new(
24     connection => $conn,
25     class => 'Object::Remote::ModuleLoader',
26     args => { module_sender => $self->module_sender }
27   )->disarm_free;
28   return $conn;
29 };
30
31 sub _perl_command { 'perl', '-' }
32
33 sub _start_perl {
34   my $self = shift;
35   my $pid = open2(
36     my $foreign_stdout,
37     my $foreign_stdin,
38     $self->_perl_command(@_),
39   ) or die "Failed to run perl at '$_[0]': $!";
40   return ($foreign_stdin, $foreign_stdout, $pid);
41 }
42
43 sub _open2_for {
44   my $self = shift;
45   my ($foreign_stdin, $foreign_stdout, $pid) = $self->_start_perl(@_);
46   print $foreign_stdin 'BEGIN { $ENV{OBJECT_REMOTE_DEBUG} = 1 }'."\n"
47     if $ENV{OBJECT_REMOTE_DEBUG};
48   print $foreign_stdin $self->fatnode_text
49     or die "Failed to send fatpacked data to new node on '$_[0]': $!";
50   return ($foreign_stdin, $foreign_stdout, $pid);
51 }
52
53 sub fatnode_text {
54   my ($self) = @_;
55   require Object::Remote::FatNode;
56   my $text = '';
57   $text .= 'BEGIN { $ENV{OBJECT_REMOTE_DEBUG} = 1 }'."\n"
58     if $ENV{OBJECT_REMOTE_DEBUG};
59   $text .= <<'END';
60 $INC{'Object/Remote/FatNode.pm'} = __FILE__;
61 $Object::Remote::FatNode::DATA = <<'ENDFAT';
62 END
63   $text .= $Object::Remote::FatNode::DATA;
64   $text .= "ENDFAT\n";
65   $text .= <<'END';
66 eval $Object::Remote::FatNode::DATA;
67 END
68   $text .= "__END__\n";
69   return $text;
70 }
71
72 1;