init.lua 1.5 KB

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