[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: [ANN] pluto + rings = springs
- From: Fabien <fleutot+lua@...>
- Date: Thu, 27 Dec 2007 16:29:16 +0100
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