Coder Social home page Coder Social logo

rmi's Introduction

NAME
    RMI - Remote Method Invocation with transparent proxies

SYNOPSIS
     #process 1: an example server on host "myserver"

        use RMI::Server::Tcp;
        
    my $s = RMI::Server::Tcp->new(port => 1234); 
        $s->run;


     #process 2: an example client

        use RMI::Client::Tcp;
        
    my $c = RMI::Client::Tcp->new(
           host => 'myserver', 
           port => 1234,
        );

        $c->call_use('IO::File'); 
        $r = $c->call_class_method('IO::File','new','/etc/passwd');

        $line1 = $r->getline;           # works as an object

        $line2 = <$r>;                  # works as a file handle
        @rest  = <$r>;                  # detects scalar/list context correctly

        $r->isa('IO::File');            # transparent in standard ways
        $r->can('getline');
        
    ref($r) eq 'RMI::ProxyObject';  # the only sign this isn't a real IO::File...
                                        # (see RMI::Client's use_remote() to fix this)

DESCRIPTION
    RMI stands for Remote Method Invocation. The RMI modules allow one
    process to have virtual object "stubs" which are proxies for real
    objects in another process. When methods are invoked on the proxy, the
    method actually runs in the other process. When results are returned,
    those values may also be proxies for the real items in the other
    process. Parameters from the client are also automatically proxied on
    the server side during method execution.

    In addition to invoking methods on proxy objects trasparently, an
    RMI::Client can invoke class methods, regular function calls, and other
    Perl functionaity on the remote server. Calls like these are typically
    the first step to obtain a remote object in the first place. This is
    different than implementations in other languages, which typically
    require that a server have limited and specific objects it returns, with
    all further proxying happening through them.

    The procedure typically goes as follows:

    1. a server is started which has access to some objects or data which is
    of value

    2. a client connects to that server, and asks that it execute code on
    its behalf

    3. the results returned may contain objects or other references, which
    the client recieves as proxies which "seem like" the real thing

    4. further interaction with the returned proxy objects/refs
    automatically make calls through the client to the server internally

METHODS
    The RMI module has no public methods of its own.

    See RMI::Client and RMI::Server for detailed API information and
    examples.

    See RMI::ProxyObject and RMI::ProxyReference for details on behavior of
    proxies.

    See RMI::Node for internals and details on the wire protocol.

PROXY OBJECTS AND REFERENCES
    A proxy object is an object on one "side" of an RMI connection which
    represents an object which really exists on the other side. When an
    RMI::Client calls a method on its associated RMI::Server, and that
    method returns a reference of any kind, a proxy is made on the client
    side, rather than a copy. The proxy object appears to be a reference to
    the real object, but internally it engages in messaging across the
    client to the server for all method calls, dereferencing, etc. It
    contains no actual data, and implements no actual methods calls.

    By the same token, when a client passes objects or other references to
    the server as parameters to a method call, the server generates a proxy
    for those objects, so that the remote method call may "call back" the
    client for detailed access to the objects it passed.

    The choice to proxy by default rather than generate a copy on the remote
    side by default is distinct from some remoting systems. It is, of
    course, possible to explicitly ask the server to serialize a given
    object, but because a serialized object may not behave the same way when
    it has lost its environment, this is not the default behavior.

    Proxied objects are only revealed as such by a call to ref(), which
    reveals the object is actually an RMI::ProxyObject. Calls to isa() and
    can() are proxied across the connection to the remote side, and will
    maintain the correct API. Remote objects which implement AUTOLOAD for
    their API will still work correctly.

    Plain proxied references, and as well as objects, are "tied" so as to
    operate as the correct type of Perl primitive. SCALAR, ARRAY, HASH, CODE
    and GLOB/IO references, blessed or otherwise, will be proxied as the
    same type of reference on the other side. The RMI system uses Perl's
    "tie" functionality to do this.

GARBAGE COLLECTION
    Until a proxy is destroyed, the side which sent the item will keep an
    additional reference to the real item, both to facilitate proxying, and
    to prevent garbage collection. Upon destruction on the reciever side, a
    message is sent to the sender to expire its link to the item in
    question, and allow garbage collection if no other references exist.

DEBUGGING RMI CODE
    When the RMI_DEBUG environment variable set to 1, the RMI modules will
    emit detailed information to STDERR during all "conversations" between
    itself and the remote side. This works for RMI::Client, RMI::Server, and
    anything else which inherits from RMI::Node.

    This value is available inside the application as $RMI::DEBUG.

    The package variable $RMI::DEBUG_MSG_PREFIX will be printed at the
    beginning of each message. Changing this value allows the viewer to
    separate both halves of a conversation. (The test suite for RMI sets
    this value to ' ' for the server side, causing server activity to be
    indented relative to client activity in the debug output.)

     RMI_DEBUG=1 perl -I lib t/01_*.t

SECURITY
  no inherent security is built-in
    If you require restrctions on what the server provides, a custom
    sub-class should be written around the server to restrict the types of
    calls it will receive.

    This is wise whenever the server is exposed to an untrusted network.

LIMITS TO TRANSPARENCY
  calls to ref($my_proxy) reveal the true class RMI::ProxyObject
    Proxied objects/references reveal that they are proxies when ref($o) is
    called on them, unless the entire package is proxied with ->use_remote.

    Calls to ->isa() still operate as though the proxy were the object it
    represents. Code which goes around the isa() override to
    UNIVERSAL::isa() will circumvent the illusion as well.

  remote objects do not stringify to matche the original object
    Like ref(), this reveals the actual reference (and possibly class) of
    the proxy, not the object which is proxied.

  calls to use_remote() does not auto-proxy all package variables
    Calls to "use_remote" will proxy subroutine calls, but not package
    variable access automatically, besides @ISA. If necessary, it must be
    done explicitly with a call to bind().

  the client may not be able to "tie" variables which are proxies
    The RMI modules use "tie" on every proxy reference to channel access to
    the other side. The effect of attempting to tie a proxy reference may
    destroy its ability to proxy. (This is untested.)

    In most cases, applications do not tie a variable created elsewhere
    because it destroys its prior value. As such this is unlikely to be a
    problem, but is still technically a hole in transparency.

  change to $_[N] values will not affect the original variable
    Remote calls to subroutines/methods which modify aliases in @_ directly
    to tamper with the caller's variables will not work as it would with a
    local method call.

    This is supportable, but adds considerable overhead to support modules
    which create a side effect which is avoided because it is, mostly, a bad
    idea.

    Perl technically passes an alias to even non-reference values, though
    the common "my ($v1,$v2) = @_;" makes a copy which safely allows the
    subroutine to behave as though the values were pass-by-copy.

     sub foo {
         $_[0]++; # BAD!
     } 
     my $v = 1; 
     foo($v); 
     $v == 2; # SURPRISE!

    If foo() were called via RMI, in the current implementation, $v would
    still have its original value.

    Packages which implement this surprise behavior include Compress::Zlib!
    If this feature were added the overhead to Compress::Zlib would still
    make you want to wrap the call...

  code which relies on caller() will probably fail
    This means that some modules which perform magic during import() may not
    work as intended.

    This problem is prevented in one place automatically by the current RMI
    implementation: there is custom code to handle exporting of methods into
    the caller's namespace inside "use_remote".

IMPLEMENTATIONS IN OTHER LANGUAGES
    The use of transparent proxy objects goes by the term "RMI" in Java,
    "Drb" in Ruby, "PYRO" in Python, "Remoting" in .NET.

    It is similar in functionality to architectures such as CORBA, SOAP, RPC
    and DCOM.

    None of the above use the same protocols (except Java's RMI has an
    optional CORBA-related implementation). This module is no exception,
    sadly. Patches are welcome.

SEE ALSO
    RMI::Server, RMI::Client, RMI::Node, RMI::ProxyObject,
    RMI::ProxyReference, SOAP, RPC

AUTHORS
    Scott Smith <[email protected]>

COPYRIGHT
    Copyright (c) 2008 - 2009 Scott Smith <[email protected]> All rights
    reserved.

LICENSE
    This program is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

    The full text of the license can be found in the LICENSE file included
    with this module.

rmi's People

Contributors

sakoht avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.