lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi,

here's a quick hack I needed, and some other people might find handy. Rings allows to create new lua states from within Lua, but there are limitations on what data can be sent across states. OTOH, Pluto offers a very complete serialization of Lua data, so I've just duct-taped them together. It could be done much better, typically by modifying the two projects and really merging the sources, instead of monkey-patching through the debug interface; with a couple of modifications, the requirement that states reside on the same machine/process can be lifted, which would open interesting perspectives (just think about zipping the network transfers, Pluto isn't optimized for space). Serialization with Pluto for Rings = SPRings.

Tested with rings 1.1 and pluto 2.0 alpha; in the latter, the function pluto_open() must be renamed luaopen_pluto() to respect Lua 5.1's module conventions. Here's the code:


--springs.lua--

require 'pluto'
require 'rings'

-- Permanent tables for Pluto's persist() and unpersist() functions.
local rings_p_perms = { }
local rings_u_perms = { }

-- Serialize, send the request to the child state, deserialize the result
local function call_send (r, ...)
   local  msg_snd = pluto.persist (rings_p_perms, {...})
   local  st, msg_rcv =
      r:dostring (string.format ("return rings.call_receive %q", msg_snd))
   if st then return unpack(pluto.unpersist (rings_u_perms, msg_rcv))
   else return st, msg_rcv end
end

-- Receive a request from the master state, deserialize it, do it,
-- serialize the result.
local function call_receive (rcv_msg)
   local args = pluto.unpersist (rings_u_perms, rcv_msg)
   local r = { pcall (unpack (args)) }
   return pluto.persist (rings_p_perms, r)
end

-- Monkey-patch rings
debug.getregistry()['state metatable'].__index.call = call_send
rings.call_receive = call_receive

local original_rings_new = rings.new
function rings.new ()
   local r = original_rings_new ()
   r:dostring [[require'springs']]
   return r
end