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