new Client/Router/Service arch
[scpubgit/Tak.git] / lib / Tak / ObjectClient.pm
CommitLineData
e49c818e 1package Tak::ObjectClient;
2
3use Tak::ObjectProxy;
4use Moo;
5
6with 'Tak::Role::ObjectMangling';
7
8has world => (is => 'ro', required => 1);
9
10has remote => (is => 'lazy');
11
12sub _build_remote {
13 my ($self) = @_;
14 my $world = $self->world;
15 $world->remote_for('meta')->blocking_request(
16 register => object_service => 'Tak::ObjectService'
17 );
18 $world->remote_for('object_service')
19}
20
21sub proxy_method_call {
22 my ($self, @call) = @_;
23 my $ready = $self->encode_objects(\@call);
24 my $context = wantarray;
25 my @res = $self->remote->blocking_request(call_method => $context => $ready);
26 if ($res[0] eq 'RESULT') {
27 my $unpacked = $self->decode_objects($res[1]);
28 if ($context) {
29 return @$unpacked;
30 } elsif (defined $context) {
31 return $unpacked->[0];
32 } else {
33 return;
34 }
35 } else {
36 die $res[1];
37 }
38}
39
40sub proxy_death {
41 my ($self, $proxy) = @_;
42 $self->remote->blocking_request(remove_object => $proxy->{tag});
43}
44
45sub inflate {
46 my ($self, $tag) = @_;
47 bless({ client => $self, tag => $tag }, 'Tak::ObjectProxy');
48}
49
50sub deflate {
51 my ($self, $obj) = @_;
52 unless (ref($obj) eq 'Tak::ObjectProxy') {
53 die "Can't deflate non-proxied object ${obj}";
54 }
55 return +{ __proxied_object__ => $obj->{tag} };
56}
57
58sub new_object {
59 my ($self, $class, @args) = @_;
60 $self->proxy_method_call($class, 'new', @args);
61}
62
631;