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