LuDO Support

LuDO stands for Lua Distributed Objects. It is an RMI technology specifically designed for use within the Lua language. Moreover, it is intended to be as simple as possible so its implementation can be easily comprehended by developers interested in development of support for other RMI technologies in OiL. Below, we describe the main characteristics of LuDO.

Configuration Options

LuDO brokers are typically created using one of the following flavors (for more information about flavors, see section Using Flavors):

ludo;base
ludo;cooperative;base

LuDO accepts only two configuration options that defines the host and port where invocations must be send to, as described below.

host string [optional] Host name or IP address. If none is provided the ORB binds to all current net interfaces.
port number [optional] Host port the ORB must listen. If none is provided, the ORB tries to bind to a port in the range [2809; 9999].

Below is an example that illustrates how to initiate a LuDO broker:

require "oil"

oil.main(function()
  local broker = oil.init{
    flavor = "ludo;cooperative;base",
    host = "myhostname",
    port = "8080",
  }
  
  ...
  
  broker:run()
end)

Value Mapping

Similar to Lua, LuDO does not provide support for interfaces or method signatures. Instead, it relies on dynamic typing, and remote methods can be invoked with any number of parameters and can return any number of values. However, such values must be values serializable by method implemented by class loop.serial.Serializer, which includes Lua functions without upvalues shared with other functions. In particular, objects are transferred by copy and not by reference. Therefore, if you pass an object as parameter to a remote method, it will be copied to the remote context and all changes performed on the remote copy will not be reflected in the original object. To send objects by reference, you have to explicitly create a proxy for the object and send the proxy, which will be copied to the remote context. Such situation is illustrated in the code below.


Server
require "oil"

oil.main(function()
  local broker = oil.init{flavor="ludo;cooperative;base"}
  
  local Invoker = {}
  function Invoker:invoke(object, method, ...)
    object[method](object, ...)
  end
  
  oil.writeto("invoker.ref",
    broker:tostring(
      broker:newservant(Invoker)))
  
  broker:run()
end)

Client
require "oil"

oil.main(function()
  local broker = oil.init{flavor="ludo;cooperative;base"}
  oil.newthread(broker.run, broker)
  
  local Hello = {}
  function Hello:say(who)
    print(string.format("Hello, %s!", tostring(who)))
  end
  
  local Invoker = broker:newproxy(oil.readfrom("invoker.ref"))
  
  -- object 'Hello' is copied to the remote context
  -- thus the message is printed on the remote host
  Invoker:invoke(Hello, "say", "World")
  
  -- create a proxy for a servant from object 'Hello'
  local proxy = 
    broker:newproxy(
      broker:tostring(
        broker:newservant(Hello)))
  
  -- proxy to 'Hello' is copied to the remote context
  -- thus the message is printed locally
  Invoker:invoke(proxy, "say", "World")
  
  broker:shutdown()
end)

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

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