Accessing Distributed Objects

Distributed objects are represented in the local application by proxies. Proxies behave as the distributed objects they represent, thus whenever a method is called on the proxy, a corresponding method is called in the distributed object. The use of proxies is the standard way to perform remote invocations in OiL.

Creating Proxies

Proxies are implicitly created whenever the broker receives a reference to a distributed object. In such cases, the broker creates a proxy to the distributed object and passes it to the application as the return a method invocated or as parameter to a method invoked. Therefore, the application usually does not deal with creation of proxies when distributed objects are provided as parameters or as returned values of methods of distributed objects.

However, sometimes it is necessary to explicitly create a proxy for a distributed object. This usually is the case when the application starts up and the very first proxy must be created. The solution for this case is to create a proxy from textual references using method orb:newproxy. See section about Obtaining Object References for information about how textual references are created. The code below is the complete implementation of a client application that access the LuDO server in section Registering Servants.

require "oil"

oil.main(function()
  -- initialize a LuDO ORB                     
  local orb = oil.init{flavor="ludo"}
  
  -- create a proxy for remote servant
  local hello = orb:newproxy(oil.readfrom("hello.ref"))
  
  -- invoke remote method
  hello:sayto("World")

  -- terminate the application
  orb:shutdown()
end)

Invocation

With respect to methods, the proxy behaves much like the distributed object it represents. That means that when a method of a proxy is called, the method with the same name is invoked on the servant that implements the distributed object. Additionally, every argument passed to the called method is available to the servant's method. Similarly, all the values returned by the servant's method are returned by the proxy method.

It is worth stressing that the nature of some values passed as parameter, returned values or raised errors of remote invocations are suitable to subtle changes accordingly to the data transmission semantics defined by the underlying RMI protocol used by the broker. For instance, some values may be copied or event be transmitted as something different. For example, ordinary Lua errors raised by invocations on a CORBA broker are transmitted as CORBA's system exception CORBA::UNKNOWN instead of the error message that is the actual value of the error.

As consequence of the proxies trying to mimic the corresponding distributed object, generally invocations are performed synchronously. Therefore, the invoker's execution is suspended until the results of remote method's execution are ready. However, it is possible to create special proxies to perform invocations in special ways, like asynchronously or emulating a pcall (f [, arg1, ···]). For more information for special kind of proxies see method orb:newproxy.

Exceptions

The way errors are catch in Lua is by the use of function pcall (f [, arg1, ···]). However, this function was designed to catch errors in functions thus it provides a signature that is cumbersome to use to catch errors in method calls. As illustrated in the example below.

local ok, err = pcall(proxy.invoked_method, proxy)

One way to avoid this is to create an asynchronous proxy and use the method future:results of the future object returned by the operations invoked using that kind of proxy. In this approach, the example above would become.

local ok, err = orb:newproxy(proxy, "asynchronous"):invoked_method():results()

Other alternative is to use a special kind of proxy denominated protected proxy, as illustrated in the code below.

local ok, err = orb:newproxy(proxy, "protected"):invoked_method()

OiL also supports the definition exception handling functions for proxies through application provided method proxy:__setexcatch. Additionally, a single exception handler can be defined to all proxies of a given broker by method orb:setexcatch.

Timeout

OiL also supports the definition of a timeout to wait for the completion of invocations made using proxies. The timeout can be set by proxy using method proxy:__settimeout or it can be defined to all proxies of a given broker by method orb:settimeout.

Copyright (C) 2004-2014 Tecgraf, PUC-Rio

This project is currently being maintained by Tecgraf at PUC-Rio.