service_provider.lua 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. local skynet = require "skynet"
  2. local provider = {}
  3. local function new_service(svr, name)
  4. local s = {}
  5. svr[name] = s
  6. s.queue = {}
  7. return s
  8. end
  9. local svr = setmetatable({}, { __index = new_service })
  10. function provider.query(name)
  11. local s = svr[name]
  12. if s.queue then
  13. table.insert(s.queue, skynet.response())
  14. else
  15. if s.address then
  16. return skynet.ret(skynet.pack(s.address))
  17. else
  18. error(s.error)
  19. end
  20. end
  21. end
  22. local function boot(addr, name, code, ...)
  23. local s = svr[name]
  24. skynet.call(addr, "lua", "init", code, ...)
  25. local tmp = table.pack( ... )
  26. for i=1,tmp.n do
  27. tmp[i] = tostring(tmp[i])
  28. end
  29. if tmp.n > 0 then
  30. s.init = table.concat(tmp, ",")
  31. end
  32. s.time = skynet.time()
  33. end
  34. function provider.launch(name, code, ...)
  35. local s = svr[name]
  36. if s.booting then
  37. table.insert(s.queue, skynet.response())
  38. else
  39. s.booting = true
  40. local err
  41. local ok, addr = pcall(skynet.newservice,"service_cell", name)
  42. if ok then
  43. ok, err = xpcall(boot, debug.traceback, addr, name, code, ...)
  44. else
  45. err = addr
  46. addr = nil
  47. end
  48. s.booting = nil
  49. if ok then
  50. s.address = addr
  51. for _, resp in ipairs(s.queue) do
  52. resp(true, addr)
  53. end
  54. s.queue = nil
  55. skynet.ret(skynet.pack(addr))
  56. else
  57. if addr then
  58. skynet.send(addr, "debug", "EXIT")
  59. end
  60. s.error = err
  61. for _, resp in ipairs(s.queue) do
  62. resp(false)
  63. end
  64. s.queue = nil
  65. error(err)
  66. end
  67. end
  68. end
  69. function provider.test(name)
  70. local s = svr[name]
  71. if s.booting then
  72. skynet.ret(skynet.pack(nil, true)) -- booting
  73. elseif s.address then
  74. skynet.ret(skynet.pack(s.address))
  75. elseif s.error then
  76. error(s.error)
  77. else
  78. skynet.ret() -- nil
  79. end
  80. end
  81. skynet.start(function()
  82. skynet.dispatch("lua", function(session, address, cmd, ...)
  83. provider[cmd](...)
  84. end)
  85. skynet.info_func(function()
  86. local info = {}
  87. for k,v in pairs(svr) do
  88. local status
  89. if v.booting then
  90. status = "booting"
  91. elseif v.queue then
  92. status = "waiting(" .. #v.queue .. ")"
  93. end
  94. info[skynet.address(v.address)] = {
  95. init = v.init,
  96. name = k,
  97. time = os.date("%Y %b %d %T %z",math.floor(v.time)),
  98. status = status,
  99. }
  100. end
  101. return info
  102. end)
  103. end)