start adding logs and add support for routed logs and logging to stderr
[scpubgit/Object-Remote.git] / lib / Object / Remote / Handle.pm
1 package Object::Remote::Handle;
2
3 use Object::Remote::Proxy;
4 use Scalar::Util qw(weaken blessed);
5 use Object::Remote::Future;
6 #must find way to exclude certain log events
7 #from being forwarded - log events generated in
8 #response to log events cause exploding
9 #use Object::Remote::Logging qw(:log);
10 use Module::Runtime qw(use_module);
11 use Moo;
12
13 has connection => (
14   is => 'ro', required => 1,
15   coerce => sub {
16     blessed($_[0])
17       ? $_[0]
18       : use_module('Object::Remote::Connection')->new_from_spec($_[0])
19   },
20 );
21
22 has id => (is => 'rwp');
23
24 has disarmed_free => (is => 'rwp');
25
26 sub disarm_free { $_[0]->_set_disarmed_free(1); $_[0] }
27
28 sub proxy {
29   bless({ remote => $_[0], method => 'call' }, 'Object::Remote::Proxy');
30 }
31
32 sub BUILD {
33   my ($self, $args) = @_;
34 #  log_debug { "constructing instance of " . ref($self) };
35   if ($self->id) {
36     $self->disarm_free;
37   } else {
38     die "No id supplied and no class either" unless $args->{class};
39     ref($_) eq 'HASH' and $_ = [ %$_ ] for $args->{args};
40     $self->_set_id(
41       await_future(
42         $self->connection->send_class_call(
43           0, $args->{class},
44           $args->{constructor}||'new', @{$args->{args}||[]}
45         )
46       )->{remote}->disarm_free->id
47     );
48   }
49 #  log_trace { "finished constructing " . ref($self) };
50   $self->connection->register_remote($self);
51 }
52
53 sub call {
54   my ($self, $method, @args) = @_;
55   my $w = wantarray;
56   $method = "start::${method}" if (caller(0)||'') eq 'start';
57   future {
58     $self->connection->send(call => $self->id, $w, $method, @args)
59   };
60 }
61
62 sub call_discard {
63   my ($self, $method, @args) = @_;
64   $self->connection->send_discard(call => $self->id, $method, @args);
65 }
66
67 sub call_discard_free {
68   my ($self, $method, @args) = @_;
69   $self->disarm_free;
70   $self->connection->send_discard(call_free => $self->id, $method, @args);
71 }
72
73 sub DEMOLISH {
74   my ($self, $gd) = @_;
75   return if $gd or $self->disarmed_free;
76   $self->connection->send_free($self->id);
77 }
78
79 1;