File Coverage

blib/lib/Object/Remote.pm
Criterion Covered Total %
statement 28 30 93.3
branch n/a
condition 2 3 66.6
subroutine 10 12 83.3
pod 1 3 33.3
total 41 48 85.4


line stmt bran cond sub pod time code
1             package Object::Remote;
2              
3 13     13   889615 use Object::Remote::MiniLoop;
  13         52  
  13         503  
4 13     13   5884 use Object::Remote::Loop;
  13         32  
  13         375  
5 13     13   4476 use Object::Remote::Handle;
  13         47  
  13         553  
6 13     13   74 use Object::Remote::Logging qw( :log );
  13         27  
  13         82  
7 13     13   79 use Module::Runtime qw(use_module);
  13         24  
  13         57  
8              
9             our $VERSION = '0.005001'; # v0.5.1
10              
11             sub new::on {
12 20     20   625858 my ($class, $on, @args) = @_;
13 20         173 my $conn = __PACKAGE__->connect($on);
14 20     0   869 log_trace { sprintf("constructing instance of $class on connection for child pid of %i", $conn->child_pid) };
  0         0  
15 20         302 return $conn->remote_object(class => $class, args => \@args);
16             }
17              
18             sub can::on {
19 2     2   2451 my ($class, $on, $name) = @_;
20 2         14 my $conn = __PACKAGE__->connect($on);
21 2     0   44 log_trace { "Invoking remote \$class->can('$name')" };
  0         0  
22 2         31 return $conn->remote_sub(join('::', $class, $name));
23             }
24              
25             sub new {
26 1     1 0 43 shift;
27 1         25 Object::Remote::Handle->new(@_)->proxy;
28             }
29              
30             sub connect {
31 28     28 1 876605 my ($class, $to, @args) = @_;
32 28         177 use_module('Object::Remote::Connection')->maybe::start::new_from_spec($to, @args);
33             }
34              
35             sub current_loop {
36 748   66 748 0 20234 our $Current_Loop ||= Object::Remote::Loop->new;
37             }
38              
39             1;
40              
41             =head1 NAME
42              
43             Object::Remote - Call methods on objects in other processes or on other hosts
44              
45             =head1 SYNOPSIS
46              
47             Creating a connection:
48              
49             use Object::Remote;
50              
51             my $conn = Object::Remote->connect('myserver'); # invokes ssh
52              
53             Calling a subroutine:
54              
55             my $capture = IPC::System::Simple->can::on($conn, 'capture');
56              
57             warn $capture->('uptime');
58              
59             Using an object:
60              
61             my $eval = Eval::WithLexicals->new::on($conn);
62              
63             $eval->eval(q{my $x = `uptime`});
64              
65             warn $eval->eval(q{$x});
66              
67             Importantly: 'myserver' only requires perl 5.8+ - no non-core modules need to
68             be installed on the far side, Object::Remote takes care of it for you!
69              
70             =head1 DESCRIPTION
71              
72             Object::Remote allows you to create an object in another process - usually
73             one running on another machine you can connect to via ssh, although there
74             are other connection mechanisms available.
75              
76             The idea here is that in many cases one wants to be able to run a piece of
77             code on another machine, or perhaps many other machines - but without having
78             to install anything on the far side.
79              
80             =head1 COMPONENTS
81              
82             =head2 Object::Remote
83              
84             The "main" API, which provides the L method to create a connection
85             to a remote process/host, L to create an object on a connection,
86             and L to retrieve a subref over a connection.
87              
88             =head2 Object::Remote::Connection
89              
90             The object representing a connection, which provides the
91             L and
92             L methods that are used by
93             L and L to return proxies for objects and subroutines
94             on the far side.
95              
96             =head2 Object::Remote::Future
97              
98             Code for dealing with asynchronous operations, which provides the
99             L syntax for calling a possibly
100             asynchronous method without blocking, and
101             L and L
102             to block until an asynchronous call completes or fails.
103              
104             =head1 METHODS
105              
106             =head2 connect
107              
108             my $conn = Object::Remote->connect('-'); # fork()ed connection
109              
110             my $conn = Object::Remote->connect('myserver'); # connection over ssh
111              
112             my $conn = Object::Remote->connect('user@myserver'); # connection over ssh
113              
114             my $conn = Object::Remote->connect('root@'); # connection over sudo
115              
116             =head2 new::on
117              
118             my $eval = Eval::WithLexicals->new::on($conn);
119              
120             my $eval = Eval::WithLexicals->new::on('myserver'); # implicit connect
121              
122             my $obj = Some::Class->new::on($conn, %args); # with constructor arguments
123              
124             =head2 can::on
125              
126             my $hostname = Sys::Hostname->can::on($conn, 'hostname');
127              
128             my $hostname = Sys::Hostname->can::on('myserver', 'hostname');
129              
130             =head1 ENVIRONMENT
131              
132             =over 4
133              
134             =item OBJECT_REMOTE_PERL_BIN
135              
136             When starting a new Perl interpreter the contents of this environment
137             variable will be used as the path to the executable. If the variable
138             is not set the path is 'perl'
139              
140             =item OBJECT_REMOTE_LOOP
141              
142             Forces the loop implementation to the named module. Defaults to
143             C< Object::Remote::MiniLoop >; setting this value to
144             C< IO::Async::Loop > integrates Object::Remote with IO::Async.
145              
146             =item OBJECT_REMOTE_LOG_LEVEL
147              
148             Setting this environment variable will enable logging and send all log messages
149             at the specfied level or higher to STDERR. Valid level names are: trace debug
150             verbose info warn error fatal
151              
152             =item OBJECT_REMOTE_LOG_FORMAT
153              
154             The format of the logging output is configurable. By setting this environment variable
155             the format can be controlled via printf style position variables. See
156             L.
157              
158             =item OBJECT_REMOTE_LOG_FORWARDING
159              
160             Forward log events from remote connections to the local Perl interpreter. Set to 1 to enable
161             this feature which is disabled by default. See L.
162              
163             =item OBJECT_REMOTE_LOG_SELECTIONS
164              
165             Space seperated list of class names to display logs for if logging output is enabled. Default
166             value is "Object::Remote::Logging" which selects all logs generated by Object::Remote.
167             See L.
168              
169             =back
170              
171             =head1 KNOWN ISSUES
172              
173             =over 4
174              
175             =item Large data structures
176              
177             Object::Remote communication is encapsalated with JSON and values passed to remote objects
178             will be serialized with it. When sending large data structures or data structures with a lot
179             of deep complexity (hashes in arrays in hashes in arrays) the processor time and memory requirements
180             for serialization and deserialization can be either painful or unworkable. During times of
181             serialization the local or remote nodes will be blocked potentially causing all remote
182             interpreters to block as well under worse case conditions.
183              
184             To help deal with this issue it is possible to configure resource ulimits for a Perl interpreter
185             that is executed by Object::Remote. See C
186             for details on the perl_command attribute.
187              
188             =item User can starve run loop of execution opportunities
189              
190             The Object::Remote run loop is responsible for performing I/O and managing timers in a cooperative
191             multitasing way but it can only do these tasks when the user has given control to Object::Remote.
192             There are times when Object::Remote must wait for the user to return control to the run loop and
193             during these times no I/O can be performed and no timers can be executed.
194              
195             As an end user of Object::Remote if you depend on connection timeouts, the watch dog or timely
196             results from remote objects then be sure to hand control back to Object::Remote as soon as you
197             can.
198              
199             =item Run loop favors certain filehandles/connections
200              
201             =item High levels of load can starve timers of execution opportunities
202              
203             These are issues that only become a problem at large scales. The end result of these two
204             issues is quite similiar: some remote objects may block while the local run loop is either busy
205             servicing a different connection or is not executing because control has not yet been returned to
206             it. For the same reasons timers may not get an opportunity to execute in a timely way.
207              
208             Internally Object::Remote uses timers managed by the run loop for control tasks. Under
209             high load the timers can be preempted by servicing I/O on the filehandles and execution
210             can be severely delayed. This can lead to connection watchdogs not being updated or connection
211             timeouts taking longer than configured.
212              
213             =item Deadlocks
214              
215             Deadlocks can happen quite easily because of flaws in programs that use Object::Remote or
216             Object::Remote itself so the C is available. When used the run
217             loop will periodically update the watch dog object on the remote Perl interpreter. If the
218             watch dog goes longer than the configured interval with out being updated then it will
219             terminate the Perl process. The watch dog will terminate the process even if a deadlock
220             condition has occured.
221              
222             =item Log forwarding at scale can starve timers of execution opportunities
223              
224             Currently log forwarding can be problematic at large scales. When there is a large
225             amount of log events the load produced by log forwarding can be high enough that it starves
226             the timers and the remote object watch dogs (if in use) don't get updated in timely way
227             causing them to erroneously terminate the Perl process. If the watch dog is not in use
228             then connection timeouts can be delayed but will execute when load settles down enough.
229              
230             Because of the load related issues Object::Remote disables log forwarding by default.
231             See C for information on log forwarding.
232              
233             =item IO::Async::Loop fails on nested connections
234              
235             The tests C< t/bridged.t > and C< t/chained.t > fail when using the IO::Async loop,
236             meaning that using remote objects from the remote fails under IO::Async. (Fixes welcome!)
237              
238             =back
239              
240             =head1 SUPPORT
241              
242             IRC: #web-simple on irc.perl.org
243              
244             =head1 AUTHOR
245              
246             mst - Matt S. Trout (cpan:MSTROUT)
247              
248             =head1 CONTRIBUTORS
249              
250             bfwg - Colin Newell (cpan:NEWELLC)
251              
252             phaylon - Robert Sedlacek (cpan:PHAYLON)
253              
254             triddle - Tyler Riddle (cpan:TRIDDLE)
255              
256             =head1 SPONSORS
257              
258             Parts of this code were paid for by
259              
260             Socialflow L
261              
262             Shadowcat Systems L
263              
264             =head1 COPYRIGHT
265              
266             Copyright (c) 2012 the Object::Remote L, L and
267             L as listed above.
268              
269             =head1 LICENSE
270              
271             This library is free software and may be distributed under the same terms
272             as perl itself.
273              
274             =cut