File Coverage

blib/lib/RPC/Object/Broker.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package RPC::Object::Broker;
2 1     1   3975 use strict;
  1         2  
  1         38  
3 1     1   824 use threads;
  0            
  0            
4             use threads::shared;
5             use warnings;
6             use Carp;
7             use Data::Dump qw(dump);
8             use IO::Socket::INET;
9             use Scalar::Util qw(blessed);
10             use Storable qw(thaw nfreeze);
11             #use RPC::Object;
12             use RPC::Object::Common;
13              
14             {
15             my $instance : shared;
16             sub get_instance {
17             my ($class, $port) = @_;
18             return $instance if $instance;
19             my $self : shared;
20             $self = &share({});
21             lock %{$self};
22             $self->{port} = $port;
23             share($self->{rclass});
24             share($self->{object});
25             $self->{rclass} = &share({});
26             $self->{object} = &share({});
27             bless $self, $class;
28             $instance = $self;
29             $self->{object}{ref $instance} = $instance;
30             return $instance;
31             }
32             }
33              
34             sub start {
35             my ($self) = @_;
36             my $sock = IO::Socket::INET->new(LocalPort => $self->{port},
37             Type => SOCK_STREAM,
38             Reuse => 1,
39             Listen => 10,
40             );
41             binmode $sock;
42             while (my $conn = $sock->accept()) {
43             my $thr = async {
44             $sock->close();
45             my $res = do { local $/; <$conn> };
46             $res = thaw($res);
47             print {$conn} nfreeze($self->handle($res));
48             $conn->close();
49             };
50             $thr->detach();
51             $conn->close();
52             }
53             }
54              
55             sub handle {
56             my ($self, $arg) = @_;
57             my $context = shift @$arg;
58             my $func = shift @$arg;
59             my $obj = shift @$arg;
60             if (my $pack = blessed $obj) {
61             $self->_load_module($pack);
62             lock %{$self->{object}};
63             $obj = $self->{object}{ref $obj};
64             }
65             else {
66             $self->_load_module($obj);
67             }
68             my @ret;
69             {
70             no strict;
71             @ret = $context eq WANT_SCALAR
72             ? scalar eval { $obj->$func(@$arg) }
73             : eval { $obj->$func(@$arg) };
74             if (blessed $ret[0]) {
75             lock %{$self->{object}};
76             $self->{object}{ref $ret[0]} = $ret[0];
77             }
78             }
79             return $@ ? [RESPONSE_ERROR, $@] : [RESPONSE_NORMAL, @ret];
80             }
81              
82             sub _load_module {
83             my ($self, $pack) = @_;
84             eval qq{ require $pack };
85             die $@ if $@;
86             return;
87             }
88              
89             1;