add meta service
[scpubgit/Tak.git] / lib / Tak / WorldHandle.pm
1 package Tak::WorldHandle;
2
3 use IPC::Open2 ();
4 use Tak::Router;
5 use Tak::JSONChannel;
6 use Tak::ModuleSender;
7 use Tak::Remote;
8 use IO::All;
9 use Moo;
10
11 sub Tak::WorldHandle::_local::open2 {
12   shift;
13   my $pid = IPC::Open2::open2(my $out, my $in, @_)
14     or die "Couldn't open2 child: $!";
15   return ($in, $out, $pid);
16 }
17
18 has connection => (is => 'ro', required => 1);
19
20 sub new_local {
21   shift->new(connection => bless({}, 'Tak::WorldHandle::_local'))
22 }
23
24 sub new_remote {
25   my ($class, $target) = @_;
26   $class->new(connection => do {
27     require Net::OpenSSH;
28     Net::OpenSSH->new($target);
29   });
30 }
31
32 has router => (is => 'lazy');
33
34 sub _build_router {
35   my ($self) = @_;
36
37   my ($stdin, $stdout) = $self->connection->open2('perl -');
38
39   $stdin->print(io('takd')->all, "__END__\n");
40
41   my $channel = Tak::JSONChannel->new(
42     read_fh => $stdout, write_fh => $stdin
43   );
44
45   my $router = Tak::Router->new(
46     channel => $channel
47   );
48
49   $router->register(module_sender => Tak::ModuleSender->new);
50
51   return $router;
52 }
53
54 sub remote_for {
55   my ($self, $name) = @_;
56   Tak::Remote->new(router => $self->router, name => $name);
57 }
58
59 1;