![]()
|
ROMP - The Ruby Object Message Proxy(C) Copyright 2001 Paul Brannan (cout at rm-f.net)ROMP is a set of classes for providing distributed object support to a Ruby program. You may distribute and/or modify it under the same terms as Ruby (see http://www.ruby-lang.org/en/LICENSE.txt). Example: Client ------ client = ROMP::Client.new('localhost', 4242) obj = client.resolve("foo") puts obj.foo("foo") obj.oneway(:foo, "foo") Server ------ class Foo def foo(x); return x; end end obj = Foo.new server = ROMP::Server.new('localhost', 4242) server.bind(obj, "foo") server.thread.join You can do all sorts of cool things with ROMP, including passing blocks to the functions, throwing exceptions and propogating them from server to client, and more. Unlike CORBA, where you must create an interface definition and strictly adhere to it, ROMP uses marshalling, so you can use almost any object with it. But, alas, it is not as powerful as CORBA. On a fast machine, you should expect around 7000 messages per second with normal method calls, up to 10000 messages per second with oneway calls with sync, and up to 40000 messages per second for oneway calls without sync. The ROMP message format is broken into 3 components: [ msg_type, obj_id, message ] For each msg_type, there is a specific format to the message. Additionally, certain msg_types are only valid when being sent to the server, and others are valid only when being sent back to the client. Here is a summary: msg_type send to meaning of obj_id msg format ---------------------------------------------------------------------------- REQUEST server obj to talk to [:method, *args] REQUEST_BLOCK server obj to talk to [:method, *args] ONEWAY server obj to talk to [:method, *args] ONEWAY_SYNC server obj to talk to [:method, *args] RETVAL client always 0 retval EXCEPTION client always 0 $! YIELD client always 0 [value, value, ...] SYNC either 0=request, 1=response nil NULL_MSG either always 0 n/a BUGS: - On a 2.2 kernel, oneway calls without sync is very slow. - UDP support does not currently work.
Author: Paul Brannan module ROMPclass Server < ObjectThe ROMP server class. Like its drb equivalent, this class spawns off a new thread which processes requests, allowing the server to do other things while it is doing processing for a distributed object. This means, though, that all objects used with ROMP must be thread-safe.Methodsinitialize(endpoint, acceptor=nil, debug=false)
create_reference(obj)
Register an object with the server. The object will be given an
id of @next_id, and @next_id will be incremented. We could use the
object's real id, but this is insecure. The supplied object must
be thread-safe.
delete_reference(obj)
bind(obj, name)
This keeps the client from seeing our objects when they call inspect
Methodsinspect()
server_loop(session)
class Client < ObjectThe ROMP client class. A ROMP server must be started on the given host and port before instantiating a ROMP client.Methodsinitialize(endpoint, sync=true)
resolve(object_name)
Given a string, return a proxy object that will forward requests
for an object on the server with that name.
class Null_Mutex < ObjectIn case the user does not want synchronization.Methodssynchronize
lock
unlock
class Functions < ObjectAll the special functions we have to keep track ofConstants
class Object_Reference < ObjectA ROMP::Object_Reference is created on the server side to represent an object in the system. It can be returned from a server object to a client object, at which point it is converted into a ROMP::Proxy_Object.Methodsinitialize(object_id)
class Proxy_Object < ObjectA ROMP::Object acts as a proxy; it forwards most methods to the server for execution. When you make calls to a ROMP server, you will be making the calls through a Proxy_Object.Methodsmethod_missing(function, *args)
onweway(function, *args)
oneway_sync(function, *args)
sync()
#{method}(*args)
#{method}(*args)
#{method}(*args)
#{method}(arg, *args)
class Resolve_Server < ObjectThe Resolve_Server class registers objects for the server. You will never have to use this class directly.Methodsinitialize
register(obj)
get_object(object_id)
unregister(obj)
bind(name, id)
resolve(name)
delete_obj_from_array_private(array, obj)
class Resolve_Obj < ObjectThe Resolve_Obj class handles resolve requests for the client. It is a special ROMP object with an object id of 0. You will never have to make calls on it directly, but will instead make calls on it through the Client object.Methodsinitialize(resolve_server)
resolve(name)
class Generic_Server < ObjectA Generic_Server creates an endpoint to listen on, waits for connections, and accepts them when requested. It can operate on different kinds of connections. You will never have to use this object directly.Methodsinitialize(endpoint)
accept
class Generic_Client < ObjectA Generic_Client connects to a Generic_Server on a given endpoint. You will never have to use this object directly.Methodsself.new(endpoint)
self.print_exception(exc)
class Session < ObjectThe Sesssion class is defined in romp_helper.so. You should never have to use it directly.Requires / Includessocketthread fcntl romp_helper |