File Coverage

blib/lib/Object/Remote/Handle.pm
Criterion Covered Total %
statement 52 65 80.0
branch 10 12 83.3
condition 8 12 66.6
subroutine 14 23 60.8
pod 0 7 0.0
total 84 119 70.5


line stmt bran cond sub pod time code
1             package Object::Remote::Handle;
2              
3 15     15   4755 use Object::Remote::Proxy;
  15         24  
  15         365  
4 15     15   63 use Scalar::Util qw(weaken blessed);
  15         17  
  15         835  
5 15     15   53 use Object::Remote::Logging qw ( :log :dlog router );
  15         15  
  15         78  
6 15     15   4743 use Object::Remote::Future;
  15         29  
  15         977  
7 15     15   97 use Module::Runtime qw(use_module);
  15         19  
  15         110  
8 15     15   514 use Moo;
  15         25  
  15         90  
9              
10 15     15   4627 BEGIN { router()->exclude_forwarding }
11              
12             has connection => (
13             is => 'ro', required => 1, handles => ['is_valid'],
14             coerce => sub {
15             blessed($_[0])
16             ? $_[0]
17             : use_module('Object::Remote::Connection')->new_from_spec($_[0])
18             },
19             );
20              
21             has id => (is => 'rwp');
22              
23             has disarmed_free => (is => 'rwp');
24              
25 167     167 0 1040 sub disarm_free { $_[0]->_set_disarmed_free(1); $_[0] }
  167         396  
26              
27             sub proxy {
28 109     109 0 1601 bless({ remote => $_[0], method => 'call' }, 'Object::Remote::Proxy');
29             }
30              
31             sub BUILD {
32 128     128 0 2803 my ($self, $args) = @_;
33 128     0   949 log_trace { "constructing remote handle" };
  0         0  
34 128 100       1641 if ($self->id) {
35 88     0   454 log_trace { "disarming free for this handle" };
  0         0  
36 88         1093 $self->disarm_free;
37             } else {
38 40 50       139 die "No id supplied and no class either" unless $args->{class};
39 40   100     297 ref($_) eq 'HASH' and $_ = [ %$_ ] for $args->{args};
40 40     0   251 log_trace { "fetching id for handle and disarming free on remote side" };
  0         0  
41             $self->_set_id(
42             await_future(
43             $self->connection->send_class_call(
44             0, $args->{class},
45 40 100       295 $args->{constructor}||'new', @{$args->{args}||[]}
46             )
47             )->{remote}->disarm_free->id
48 40   50     758 );
49             }
50 127     0   1392 Dlog_trace { "finished constructing remote handle; id is $_" } $self->id;
  0         0  
51 127         2027 $self->connection->register_remote($self);
52             }
53              
54             sub call {
55 92     92 0 242 my ($self, $method, @args) = @_;
56 92         143 my $w = wantarray;
57 92         436 my $id = $self->id;
58              
59 92 100 50     468 $method = "start::${method}" if (caller(0)||'') eq 'start';
60 92     0   979 log_trace { "call('$method') has been invoked on remote handle '$id'; creating future" };
  0         0  
61              
62             future {
63 92     92   1118 log_debug { "Invoking send on connection for handle '$id' method '$method'" };
  0         0  
64 92         1308 $self->connection->send(call => $id, $w, $method, @args)
65 92         1489 };
66             }
67              
68             sub call_discard {
69 0     0 0 0 my ($self, $method, @args) = @_;
70 0     0   0 log_trace { "invoking send_discard() with 'call' for method '$method' on connection for remote handle" };
  0         0  
71 0         0 $self->connection->send_discard(call => $self->id, $method, @args);
72             }
73              
74             sub call_discard_free {
75 21     21 0 74 my ($self, $method, @args) = @_;
76 21         75 $self->disarm_free;
77 21     0   141 log_trace { "invoking send_discard() with 'call_free' for method '$method' on connection for remote handle" };
  0         0  
78 21         422 $self->connection->send_discard(call_free => $self->id, $method, @args);
79             }
80              
81             sub DEMOLISH {
82 126     126 0 29466 my ($self, $gd) = @_;
83 126     0   876 Dlog_trace { "Demolishing remote handle $_" } $self->id;
  0         0  
84 126 100 66     4158 return if $gd or $self->disarmed_free;
85             #this could happen after the connection has gone away
86 19         49 eval { $self->connection->send_free($self->id) };
  19         192  
87 19 50 66     553 if ($@ && $@ !~ m/^Attempt to invoke _send on a connection that is not valid/) {
88 0           die "Could not invoke send_free on connection for handle " . $self->id;
89             }
90             }
91              
92             1;