123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- local skynet = require "skynet"
- local command = {}
- local database = {}
- local wait_queue = {}
- local mode = {}
- local function query(db, key, ...)
- if key == nil then
- return db
- else
- return query(db[key], ...)
- end
- end
- function command.QUERY(key, ...)
- local d = database[key]
- if d ~= nil then
- return query(d, ...)
- end
- end
- local function update(db, key, value, ...)
- if select("#",...) == 0 then
- local ret = db[key]
- db[key] = value
- return ret, value
- else
- if db[key] == nil then
- db[key] = {}
- end
- return update(db[key], value, ...)
- end
- end
- local function wakeup(db, key1, ...)
- if key1 == nil then
- return
- end
- local q = db[key1]
- if q == nil then
- return
- end
- if q[mode] == "queue" then
- db[key1] = nil
- if select("#", ...) ~= 1 then
- -- throw error because can't wake up a branch
- for _,response in ipairs(q) do
- response(false)
- end
- else
- return q
- end
- else
- -- it's branch
- return wakeup(q , ...)
- end
- end
- function command.UPDATE(...)
- local ret, value = update(database, ...)
- if ret ~= nil or value == nil then
- return ret
- end
- local q = wakeup(wait_queue, ...)
- if q then
- for _, response in ipairs(q) do
- response(true,value)
- end
- end
- end
- local function waitfor(db, key1, key2, ...)
- if key2 == nil then
- -- push queue
- local q = db[key1]
- if q == nil then
- q = { [mode] = "queue" }
- db[key1] = q
- else
- assert(q[mode] == "queue")
- end
- table.insert(q, skynet.response())
- else
- local q = db[key1]
- if q == nil then
- q = { [mode] = "branch" }
- db[key1] = q
- else
- assert(q[mode] == "branch")
- end
- return waitfor(q, key2, ...)
- end
- end
- skynet.start(function()
- skynet.dispatch("lua", function (_, _, cmd, ...)
- if cmd == "WAIT" then
- local ret = command.QUERY(...)
- if ret ~= nil then
- skynet.ret(skynet.pack(ret))
- else
- waitfor(wait_queue, ...)
- end
- else
- local f = assert(command[cmd])
- skynet.ret(skynet.pack(f(...)))
- end
- end)
- end)
|