remoting works
[scpubgit/Object-Remote.git] / lib / Object / Remote.pm
CommitLineData
9e72f0cf 1package Object::Remote;
2
3use Object::Remote::MiniLoop;
4use Object::Remote::Proxy;
84b04178 5use Scalar::Util qw(weaken blessed);
6use Module::Runtime qw(use_module);
9e72f0cf 7use Moo;
8
84b04178 9sub new::on {
10 my ($class, $on, @args) = @_;
11 __PACKAGE__->new(
12 connection => $on,
13 class => $class,
14 args => \@args
15 )->proxy;
16}
17
18has connection => (
19 is => 'ro', required => 1,
20 coerce => sub {
21 blessed($_[0])
22 ? $_[0]
23 : use_module('Object::Remote::Connection')->new_from_spec($_[0])
24 },
25);
9e72f0cf 26
27has id => (is => 'rwp');
28
ad4f54b2 29has disarmed_free => (is => 'rwp');
30
31sub disarm_free { $_[0]->_set_disarmed_free(1); $_[0] }
32
2065b08b 33sub proxy {
34 bless({ remote => $_[0], method => 'call' }, 'Object::Remote::Proxy');
9e72f0cf 35}
36
37sub BUILD {
38 my ($self, $args) = @_;
39 unless ($self->id) {
40 die "No id supplied and no class either" unless $args->{class};
542d5b5c 41 ref($_) eq 'HASH' and $_ = [ %$_ ] for $args->{args};
9e72f0cf 42 $self->_set_id(
43 $self->_await(
44 $self->connection->send(
84b04178 45 class_call => $args->{class}, 0,
9e72f0cf 46 $args->{constructor}||'new', @{$args->{args}||[]}
47 )
ad4f54b2 48 )->{remote}->disarm_free->id
9e72f0cf 49 );
50 }
51 $self->connection->register_remote($self);
52}
53
54sub current_loop {
55 our $Current_Loop ||= Object::Remote::MiniLoop->new
56}
57
58sub call {
9d804009 59 my ($self, $method, @args) = @_;
84b04178 60 $self->_await(
61 $self->connection->send(call => $self->id, wantarray, $method, @args)
62 );
9e72f0cf 63}
64
2065b08b 65sub call_discard {
66 my ($self, $method, @args) = @_;
67 $self->connection->send_discard(call => $self->id, $method, @args);
68}
69
8131a88a 70sub call_discard_free {
71 my ($self, $method, @args) = @_;
72 $self->disarm_free;
73 $self->connection->send_discard(call_free => $self->id, $method, @args);
74}
75
9e72f0cf 76sub _await {
77 my ($self, $future) = @_;
78 my $loop = $self->current_loop;
79 $future->on_ready(sub { $loop->stop });
80 $loop->run;
84b04178 81 wantarray ? $future->get : ($future->get)[0];
9e72f0cf 82}
83
84sub DEMOLISH {
85 my ($self, $gd) = @_;
ad4f54b2 86 return if $gd or $self->disarmed_free;
9e72f0cf 87 $self->connection->send_free($self->id);
88}
89
901;