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