Files
skynet/service/sharedatad.lua
2014-07-30 12:10:30 +08:00

119 lines
2.1 KiB
Lua

local skynet = require "skynet"
local sharedata = require "sharedata.corelib"
local table = table
local NORET = {}
local pool = {}
local objmap = {}
local function newobj(name, tbl)
assert(pool[name] == nil)
local cobj = sharedata.host.new(tbl)
sharedata.host.incref(cobj)
local v = { value = tbl , obj = cobj, watch = {} }
objmap[cobj] = v
pool[name] = v
end
local function collectobj()
while true do
skynet.sleep(600 * 100) -- sleep 10 min
collectgarbage()
for obj, v in pairs(objmap) do
if v == true then
if sharedata.host.getref(obj) <= 0 then
objmap[obj] = nil
sharedata.host.delete(obj)
end
end
end
end
end
local CMD = {}
function CMD.new(name, t)
local dt = type(t)
local value
if dt == "table" then
value = t
elseif dt == "string" then
value = {}
local f = load(t, "=" .. name, "t", env)
f()
elseif dt == "nil" then
value = {}
else
error ("Unknown data type " .. dt)
end
newobj(name, value)
end
function CMD.delete(name)
local v = assert(pool[name])
pool[name] = nil
assert(objmap[v.obj])
objmap[v.obj] = true
sharedata.host.decref(v.obj)
for _,response in ipairs(v.watch) do
response(true)
end
end
function CMD.query(name)
local v = assert(pool[name])
local obj = v.obj
sharedata.host.incref(obj)
return v.obj
end
function CMD.confirm(cobj)
if objmap[cobj] then
sharedata.host.decref(cobj)
end
return NORET
end
function CMD.update(name, t)
local v = pool[name]
local watch, oldcobj
if v then
watch = v.watch
oldcobj = v.obj
objmap[oldcobj] = true
sharedata.host.decref(oldcobj)
pool[name] = nil
end
CMD.new(name, t)
local newobj = pool[name].obj
if watch then
sharedata.host.markdirty(oldcobj)
for _,response in ipairs(watch) do
response(true, newobj)
end
end
end
function CMD.monitor(name, obj)
local v = assert(pool[name])
if obj ~= v.obj then
return v.obj
end
table.insert(v.watch, skynet.response())
return NORET
end
skynet.start(function()
skynet.fork(collectobj)
skynet.dispatch("lua", function (session, source ,cmd, ...)
local f = assert(CMD[cmd])
local r = f(...)
if r ~= NORET then
skynet.ret(skynet.pack(r))
end
end)
end)