init.lua
1.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
local skynet = require "skynet"
local service = require "skynet.service"
local core = require "skynet.datasheet.core"
local datasheet_svr
skynet.init(function()
datasheet_svr = service.query "datasheet"
end)
local datasheet = {}
local sheets = setmetatable({}, {
__gc = function(t)
skynet.send(datasheet_svr, "lua", "close")
end,
})
local function querysheet(name)
return skynet.call(datasheet_svr, "lua", "query", name)
end
local function updateobject(name)
local t = sheets[name]
if not t.object then
t.object = core.new(t.handle)
end
local function monitor()
local handle = t.handle
local newhandle = skynet.call(datasheet_svr, "lua", "monitor", handle)
core.update(t.object, newhandle)
t.handle = newhandle
skynet.send(datasheet_svr, "lua", "release", handle)
return monitor()
end
skynet.fork(monitor)
end
function datasheet.query(name)
local t = sheets[name]
if not t then
t = {}
sheets[name] = t
end
if t.error then
error(t.error)
end
if t.object then
return t.object
end
if t.queue then
local co = coroutine.running()
table.insert(t.queue, co)
skynet.wait(co)
else
t.queue = {} -- create wait queue for other query
local ok, handle = pcall(querysheet, name)
if ok then
t.handle = handle
updateobject(name)
else
t.error = handle
end
local q = t.queue
t.queue = nil
for _, co in ipairs(q) do
skynet.wakeup(co)
end
end
if t.error then
error(t.error)
end
return t.object
end
return datasheet