service_provider.lua 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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.address then
  37. return skynet.ret(skynet.pack(s.address))
  38. end
  39. if s.booting then
  40. table.insert(s.queue, skynet.response())
  41. else
  42. s.booting = true
  43. local err
  44. local ok, addr = pcall(skynet.newservice,"service_cell", name)
  45. if ok then
  46. ok, err = xpcall(boot, debug.traceback, addr, name, code, ...)
  47. else
  48. err = addr
  49. addr = nil
  50. end
  51. s.booting = nil
  52. if ok then
  53. s.address = addr
  54. for _, resp in ipairs(s.queue) do
  55. resp(true, addr)
  56. end
  57. s.queue = nil
  58. skynet.ret(skynet.pack(addr))
  59. else
  60. if addr then
  61. skynet.send(addr, "debug", "EXIT")
  62. end
  63. s.error = err
  64. for _, resp in ipairs(s.queue) do
  65. resp(false)
  66. end
  67. s.queue = nil
  68. error(err)
  69. end
  70. end
  71. end
  72. function provider.test(name)
  73. local s = svr[name]
  74. if s.booting then
  75. skynet.ret(skynet.pack(nil, true)) -- booting
  76. elseif s.address then
  77. skynet.ret(skynet.pack(s.address))
  78. elseif s.error then
  79. error(s.error)
  80. else
  81. skynet.ret() -- nil
  82. end
  83. end
  84. function provider.close(name)
  85. local s = svr[name]
  86. if not s or s.booting then
  87. return skynet.ret(skynet.pack(nil))
  88. end
  89. svr[name] = nil
  90. skynet.ret(skynet.pack(s.address))
  91. end
  92. skynet.start(function()
  93. skynet.dispatch("lua", function(session, address, cmd, ...)
  94. provider[cmd](...)
  95. end)
  96. skynet.info_func(function()
  97. local info = {}
  98. for k,v in pairs(svr) do
  99. local status
  100. if v.booting then
  101. status = "booting"
  102. elseif v.queue then
  103. status = "waiting(" .. #v.queue .. ")"
  104. end
  105. info[skynet.address(v.address)] = {
  106. init = v.init,
  107. name = k,
  108. time = os.date("%Y %b %d %T %z",math.floor(v.time)),
  109. status = status,
  110. }
  111. end
  112. return info
  113. end)
  114. end)