Creating Distributed Objects
A servant is an local object that implements a distributed object. In other words, a servant is an object publicly available through the network. To create distributed objects it is necessary to register a servant for it.
Registering Servants
Servants are registered using method orb:newservant
.
Every registered servant implements a distributed object which is identified by a unique key called the object key.
If two servants are registered with the same object key, an error is raised.
However, a single object can be used as the servant of multiple distributed objects identified by different object keys.
The code below is a complete implementation of a OiL server using the LuDO RMI protocol.
require "oil" oil.main(function() -- create an object to be exported via OiL local hello = {} function hello:sayto(name) print(string.format("Hello, %s!", name)) end -- initialize a LuDO ORB local orb = oil.init{flavor="cooperative;ludo"} -- registers a servant and save a textual -- reference for it in a file 'hello.ref'. oil.writeto("hello.ref", orb:newservant(hello)) end)
Some RMI protocols supported by OiL rely on typing information to perform invocations correctly, e.g. CORBA. When one of these protocols is the one used by the broker, it is necessary to inform the interface of each distributed object being created. The code below is a implementation of the server above using a CORBA ORB.
require "oil" oil.main(function() -- create an object to be exported via OiL local hello = {} function hello:sayto(name) print(string.format("Hello, %s!", name)) end -- get the default, which is a CORBA ORB local orb = oil.init() -- load an IDL definition orb:loadidl[[ interface Hello { void sayto(in string name); }; ]] -- registers a servant with interface 'Hello' -- and save a textual reference for it in a -- file 'hello.ref'. oil.writeto("hello.ref", orb:newservant(hello, nil, "Hello")) end)
Obtaining Object References
Prior to invoke a method on a distributed object, it is necessary get a reference to the object.
The easiest way to get a reference to an object is to provide the result of orb:newservant
as the return value of a method of another distributed object, as described in the example below.
local Factory = {} function Factory:create() local hello = { say = function() print("Hello") end } return orb:newservant(hello) end
On the other hand, this approach is not feasible to get the first reference to a distributed object.
The alternative approach is to use a textual reference, which is a string containing the information necessary to generate a reference to a distributed object.
Textual references can be created by converting the result of orb:newservant
into a string using function tostring (v)
or print (···)
.
Such references can be stored in files (see auxiliary operation oil.writeto
) or passed as command-line parameters to applications.
local servant = orb:newservant(Factory) print("Stringfied Object Reference:", servant)
Deactivating Distributed Objects
Lua relies on automatic memory management by means of garbage collection. However, it is very difficult to build a reliable garbage collection mechanism over a distributed environment. OiL does not impose that its underlying RMI protocol provide this kind of support. Instead, OiL provides means for the application to manage explicitly the release of memory used by distributed object by means of deactivation.
A distributed object is deactivated by method orb:deactivate
.
After this call, its servant is removed from the broker and all resources associated to it are released.
In particular, after a distributed object is deactivated its key becomes free, so another servant can be registered with the key.