Brokers are the central concept of OiL. They maintain the list of active servants that are able to receive remote invocations. Brokers also create proxies that provide means to perform invocations on remote servants. Basically, brokers can be seen as the way invocation are performed through the distributed environment.
Brokers are created by operation <%=link("Module","oil.init
","#init")%>([config])
that returns an initialized broker.
The optional parameter config
is a table containing the description of the parameters used to initialize the broker.
If no parameter is informed, then a default broker is created and returned.
All future calls to operation <%=link("Module","oil.init
","#init")%>()
without parameters return the same default broker.
The config
table might contain field flavor
, which defines the flavor used to create the new broker.
For more information about flavors, check section <%=link"Flavors"%>.
Other additional fields are defined by the underlying RMI protocol selected for the broker.
To get details about these additional fields, see the specific documentation of the RMI protocol that your intend to use.
require "oil" oil.main(function() local broker = oil.init{ flavor = "intercepted;corba;typed;base", host = "127.0.0.1", port = 80, } broker:run() end)
Typically, the application calls method run
to start processing invocations sent to the broker.
This method executes a continuously processing every invocation destined to a servant registered in the broker.
The run
method only returns when the broker is shutdown.
It is important to notice that no invocation will be performed until the method run
starts its execution.
Therefore, if a remote operation requires some service provided by a local servant, then this operation should only be started after the run
is running.
Otherwise, a deadlock shall take place.
For example, suppose a registry
servant that provides method register(user)
.
The implementation of this method accesses some fields of the object user
.
In such case, if register(user)
is invoked before the method run
starts to execute and user
is a local servant, then the registry
will never be able to complete because user
's broker is not processing remote invocations yet.
To avoid, this problem, a possible solution is to execute method run
in a separate thread like in the example below.
For more information about threads, check section <%=link"Threads"%>
require "oil" oil.main(function() local broker = oil.init() -- call broker:run() in a new thread oil.newthread(broker.run, broker) -- continue execution while other thread -- processes remote invocations. end)
An alternative to method run
, which process invocations continuously, is to use a combination of methods pending
and step
.
The former indicates whether a remote invocation is pending to be processed or not.
The later is used to process a single invocation request.
If no invocation request is pending then step
blocks until an invocation request is received.
The following code is somewhat equivalent to invoke method run
:
while broker:pending() do broker:step() end
This model of execution is usefull to integrate OiL with other event loops when multithreading is not available.
Note however, that while method run
is executing, there is not need to call method step
.
Method shutdown
is used to stop the invocation processing being performed, and release all the resources currently used by the broker.
After a call to this method, no additional invocation is accepted.
Any further remote invocation results in errors raised in the client process.
However, every pending invocation initiated before the call of shutdown
are completed normally.
This method can be called at any time when method run
is executing, otherwise an exception is raised.
types
deactivate
(object)
getIR
()
getLIR
()
loadidl
(idlcode)
loadidlfile
(filename)
narrow
(proxy, [interface])
newdecoder
(stream)
newencoder
()
newexcept
(body)
newproxy
(reference, [interface])
newservant
(impl [, key, interface])
pending
()
run
()
setclientinterceptor
([interceptor])
setexcatch
(function, [interface])
setIR
(remoteIR)
setserverinterceptor
([interceptor])
shutdown
()
step
()
tostring
(object)
pending
()
Checks whether there is some request pending.
Method used to check whether there is some unprocessed ORB request pending.
It returns true
if there is some request pending that must be processed by the main ORB or false
otherwise.
Return values
ispending |
boolean | Indication that there is some request pending. |
Usage:
while broker:pending() do broker:step() end
step
()
Waits for an ORB request and process it.
Method used to wait for an ORB request and process it.
Only one single ORB request is processed at each call.
It returns true
if no exception is raised during request processing, or nil
and the raised exception otherwise.
Return values
success |
boolean | Indication of success on request processing. | |
exception |
table | [occasional] | Exception raised at request processing. |
Usage:
while broker:step() do print "One more request successfully processed!" end
run
()
Runs the ORB main loop.
Method used to process all remote requisitions continuously until some exception is raised.
This method implicitly initiates the ORB if it was not initialized yet.
Usage:
broker:run()
shutdown
()
Shuts down the ORB.
Stops the ORB main loop if it is executing.
All pending requests will be properly handled by the ORB after this method returns.
Usage:
broker:shutdown()
types
Internal Interface Repository used by OiL.
This field holds a reference to the object that implement the CORBA's Interface Repository used by the main ORB.
It implements the API defined by CORBA's IR plus an operation resolve(spec)
that return a registered IDL type description from a specification that might be an repository ID, an absolute name, an IDL description in Lua or an object from a remote IR.
Usage:
local iface = broker.types:lookup("MyModule::MyInterface") local iface = broker.types:lookup_id("IDL:MyModule/MyInterface:1.0")
loadidl
(idlcode)
Loads an IDL definition into the internal Interface Repository.
The IDL specified will be parsed by the LuaIDL compiler and the resulting
definitions are updated in the internal interface repository.
If any errors occurs during the parse no definitions are loaded into the IR.
Parameters:
idlcode |
string | The IDL specification to be loaded into the internal IR |
Return values
... |
table | IDL descriptors that represents the loaded definitions. |
Usage:
broker:loadidl [[ interface Hello { attribute boolean quiet; readonly attribute unsigned long count; string say_hello_to(in string msg); }; ]]
loadidlfile
(filename)
Loads an IDL file into the internal Interface Repository.
The IDL file specified will be parsed by the LuaIDL compiler and the resulting
definitions are updated in the internal interface repository.
If any errors occurs during the parse no definitions are loaded into the IR.
Parameters:
filename |
string | Path to the IDL file that must be loaded |
Return values
... |
table | IDL descriptors that represents the loaded definitions. |
Usage:
broker:loadidlfile "/usr/local/corba/idl/CosNaming.idl"
getLIR
()
Gets a reference to the integrated Interface Repository.
Method used to retrieve a reference to the integrated Interface Repository.
It returns a reference to the object that implements the internal Interface Repository and exports local cached interface definitions.
Return values:
localIR |
table | CORBA object that exports the internal Interface Repository. |
Usage:
print("Local IR IOR is:", broker:tostring(broker:getLIR()))
setIR
(remoteIR)
Sets the Interface Repository used to retrieve interface definitions.
Method used to set the remote Interface Repository that must be used to retrieve interface definitions not stored in the internal IR.
Once these definitions are acquired, they are stored in the internal IR.
Parameters:
remoteIR |
table | Proxy for the remote IR to be used |
Usage:
broker:setIR(broker:newproxy("corbaloc::coshost:8080/InterfaceRepository"))
getIR
()
Gets the Interface Repository used to retrieve interface definitions.
Method used to get a reference to the Interface Repository used to retrieve interface definitions not stored in the internal IR.
Return values:
remoteIR |
table | Proxy to the remote IR currently used. |
Usage:
broker:getIR():lookup("::MyModule::MyInterface")
newservant
(impl [, key, interface])
Creates a new servant from a table containing operations and attribute values.
Method used to create a new servant from a table containing attribute values and operation implementations.
The value of impl
is used as the implementation of the a servant with interface defined by parameter interface
(e.g. repository ID or absolute name of a given IDL interface stored in the IR).
Optionally, an object key value may be specified to create persistent references.
The servant returned by this method offers all servant attributes and methods, as well as implicit basic operations like CORBA's _interface
or _is_a
.
After this call any requests which object key matches the key of the servant are dispatched to its implementation.
Parameters:
impl |
table | Value used as the servant implementation (may be an indexable value, e.g. userdata with a metatable that defines the __index field) | |
interface |
string | Repository ID or absolute name of the interface the object supports | |
key |
string | [optional] | User-defined object key used in creation of the object reference |
Return values:
object |
table | Servant created. |
Usage:
broker:newservant({say_hello_to=print}, "Key", "::HelloWorld::Hello") broker:newservant({say_hello_to=print}, nil, "::HelloWorld::Hello") broker:newservant({say_hello_to=print}, nil, "IDL:HelloWorld/Hello:1.0")
deactivate
(object)
Deactivates a servant by removing its implementation from the object map.
If object
is a servant (i.e. the object returned by newservant
) then it is deactivated.
Alternatively, the object
parameter may be the servant's object key.
Only in the case that the servant was created with an implicitly created key by the ORB then the object
can be the servant's implementation.
Since a single implementation object can be used to create many servants with different interface, in this case the type
parameter must be provided with the exact servant's interface.
Parameters:
object |
table|string | Servant's object key, servant's implementation or servant itself. | |
interface |
string | [occasional] | Identification of the servant's interface (e.g. repository ID or absolute name). |
Usage:
broker:deactivate(broker:newservant(impl, "::MyInterface", "objkey")) broker:deactivate("objkey") broker:deactivate(impl, "MyInterface")
tostring
(object)
Returns textual information that identifies the servant.
This method is used to get textual information that references a servant or proxy like an IOR (Inter-operable Object Reference).
Parameters:
object |
table | Servant's object key, servant's implementation or servant itself. |
Return values:
textualref |
string | Textual reference to the servant. |
Usage:
oil.writeto("ref.ior", broker:tostring(broker:newservant(impl, "::Hello")))
newproxy
(reference, [interface])
Creates a proxy for a remote object defined by a textual reference.
The value of reference must be a string containing reference information of the object the new new proxy will represent like a stringfied IOR (Inter-operable Object Reference) or corbaloc.
Optionally, an interface supported by the remote object may be defined, in this case no attempt is made to determine the actual object interface, i.e. no network communication is made to check the object's interface.
Parameters
reference |
string | Textual representation of object's reference the new proxy will represent. | |
interface |
string | [optional] | Interface identification in the interface repository, like a repID or absolute name of a interface the remote object supports (no interface or type check is done). |
Return values
proxy |
table | Proxy to the referenced object. |
Usage:
broker:newproxy("IOR:00000002B494...") broker:newproxy("IOR:00000002B494...", "HelloWorld::Hello") broker:newproxy("IOR:00000002B494...", "IDL:HelloWorld/Hello:1.0") broker:newproxy("corbaloc::host:8080/Key", "IDL:HelloWorld/Hello:1.0")
narrow
(proxy, [interface])
Narrows an object reference into some more specific interface.
Method used to narrow an object proxy into some more specific interface.
If you wish to create a narrowed proxy from an IOR or corbaloc URL, use the newproxy
method.
The interface the object reference must be narrowed into is defined by the repository ID or absolute name stored in parameter interface
.
If no interface is defined, then the object reference is narrowed to the most specific interface supported by the COBRA object.
Note that in the former case, no attempt is made to determine the actual object interface, i.e. no network communication is made to check the object's interface.
Parameters:
proxy |
table | Proxy of a CORBA object that must be narrowed | |
interface |
string | [optional] | Repository Interface ID or absolute name of the interface the object reference must be narrowed into (no interface or type check is made) |
Return values:
proxy |
table | Proxy to the CORBA object narrowed into some interface supported by the CORBA object. |
Usage:
broker:narrow(ns:resolve_str("HelloWorld")) broker:narrow(ns:resolve_str("HelloWorld"), "IDL:HelloWorld/Hello:1.0") broker:narrow(ns:resolve_str("HelloWorld"), "::HelloWorld::Hello")
See also: newproxy
newdecoder
(stream)
Creates a new value decoder that extracts marshaled values from strings.
The decoder reads CORBA's CDR encapsulated streams, i.e. includes an indication of the endianess used in value codification.
Parameters:
stream |
string | String containing a stream with marshaled values. |
Return values:
decoder |
object | Value decoder that provides operation 'get([type])' to unmarshal values from a marshaled stream. |
Usage:
local decoder = broker:newdecoder(stream) val = decoder:get(oil.corba.idl.sequence{oil.corba.idl.long}) val = decoder:get(broker.types:lookup("MyLongSeq"))
newencoder
()
Creates a new value encoder that marshal values into strings.
The encoder marshals values in a CORBA's CDR encapsulated stream, i.e. includes an indication of the endianess used in value codification.
Return values:
encoder |
object | Value encoder that provides operation 'put(value, [type])' to marshal values and operation 'getdata()' to get the marshaled stream. |
Usage:
local encoder = broker:newencoder() encoder:put({1,2,3}, oil.corba.idl.sequence{oil.corba.idl.long}) encoder:put({1,2,3}, broker.types:lookup("MyLongSeq")) io.write(encoder:getdata())
newexcept
(body)
Creates a new exception object with the given body.
The body
must contain the values of the exceptions fields and must also contain the exception identification in index 1 (in CORBA this identification is the repository ID, absolute name, etc.).
Parameters:
body |
table | Exception body with all its field values and exception ID. |
Return values:
exception |
table | Exception that provides meta-method __tostring that provides a pretty-printing. |
Usage:
error(broker:newexcept{ "::CORBA::INTERNAL", minor_code_value = 2 })
setexcatch
(func [, interface])
Defines a exception handling function for proxies.
The handling function receives the following parameters:
proxy: object proxy that performed the operation.
exception: exception/error raised.
operation: descriptor of the operation that raised the exception.
If the parameter type
is provided, then the exception handling function will be applied only to proxies of that type (i.e. interface).
Exception handling functions are not cumulative.
For example, is the is an exception handling function defined for all proxies and other only for proxies of a given type, then the later will be used for proxies of that given type.
Additionally, exceptions handlers are not inherited through interface hierarchies.
Parameters:
func |
function | Exception handling function. |
Return values:
interface |
table | [optional] | Interface ID of a group of proxies (e.g. repID). |
Usage:
broker:setexcatch(function(_, except) error(tostring(except)) end)
setclientinterceptor
([interceptor])
Sets a CORBA-specific interceptor for operation invocations in the client-size.
The interceptor must provide the following operations:
sendrequest(request)
: request
structure is described below.
response_expected |
boolean | [read-only] | Flag that indicates if the server must send a response for this request. |
object_key |
string | [read-only] | Key of the object the request is addressed to. |
operation |
string | [read-only] | Name of the operation being invoked. |
service_context |
table | Defines the service context values. See ServiceContextList in CORBA specs. |
|
success |
boolean | [optional] | Set this value to cancel request and define the results:
true cancels the request and indicates to the application that invocation was successful;
false cancels the request and indicates to the application that invocation raised an exception. |
receivereply(reply)
: reply
structure is described below.
service_context |
table | [read-only] | Service context present in reply message. See ServiceContextList in CORBA specs. |
reply_status |
string | [read-only] | Enumeration value that indicates the reply status. See ReplyStatus in CORBA specs. |
success |
boolean | [optional] | Set this value to cancel the reply and replace results:
true cancels the reply and indicates to the application that invocation was successful;
false cancels the reply and indicates to the application that invocation raised an exception. |
request
and reply
are the same table in a single invocation.
Therefore, the fields of request
are also available in reply
except for those defined in the description of reply
.Parameters:
interceptor |
object | [optional] | Interceptor object that must provide the interface described above. If no value or nil is provided the the current interceptor is unregistered from the ORB. |
setserverinterceptor
([interceptor])
Sets a CORBA-specific interceptor for operation invocations in the server-size.
The interceptor must provide the following operations:
receiverequest(request)
: request
structure is described below.
service_context |
table | [read-only] | Service context present in reply message. See ServiceContextList in CORBA specs. |
request_id |
number | [read-only] | Number that identifies the request in the multiplexed channel. |
response_expected |
boolean | [read-only] | Flag that indicates if the server must send a response for this request. |
object_key |
string | [read-only] | Key of the object the request is addressed to. |
operation |
string | [read-only] | Name of the operation being invoked. |
servant |
object | [read-only] | Local object the invocation will be dispatched to. |
method |
function | [read-only] | Function that will be invoked on object servant . |
success |
boolean | [optional] | Set this value to cancel the request and define the results:
true cancels the request and indicates to the application that invocation was successful;
false cancels the request and indicates to the application that invocation raised an exception. |
sendreply(reply)
: reply
structure is described below.
service_context |
table | Set this value to define a service context values. See ServiceContextList in CORBA specs. |
|
success |
boolean | [optional] | Set this value to cancel the reply and replace results:
true cancels the reply and indicates to the application that invocation was successful;
false cancels the reply and indicates to the application that invocation raised an exception. |
request
and reply
are the same table in a single invocation.
Therefore, the fields of request
are also available in reply
except for those defined in the description of reply
.Parameters:
interceptor |
object | [optional] | Interceptor object that must provide the interface described above. If no value or nil is provided the the current interceptor is unregistered from the ORB. |