baseService.lua 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. require "skynet.manager"
  2. local skynet = require "skynet"
  3. local queue = require "skynet.queue"
  4. local profile = require "skynet.profile"
  5. local sharetable = require "skynet.sharetable"
  6. local hotfixHelper = require "hotfix.helper"
  7. local cmdParams, allQueue
  8. local CMD = {}
  9. local cs = queue()
  10. local queueCmds = {}
  11. local baseCommand = {}
  12. function baseCommand.regQueue(cmd)
  13. assert(cmd, "regQueue cmd is nil")
  14. queueCmds[cmd] = cmd
  15. end
  16. function baseCommand.run(source, filename, ...)
  17. local output = {}
  18. local function print(...)
  19. local value = {...}
  20. for k, v in ipairs(value) do
  21. value[k] = tostring(v)
  22. end
  23. table.insert(output, table.concat(value, "\t"))
  24. end
  25. local env = setmetatable({print = print, args = {...}}, {__index = _ENV})
  26. local func, err = load(source, filename, "bt", env)
  27. if not func then
  28. return {err}
  29. end
  30. local ok, err = xpcall(func, debug.traceback)
  31. if not ok then
  32. table.insert(output, err)
  33. end
  34. return output
  35. end
  36. function baseCommand.GC()
  37. collectgarbage("collect")
  38. end
  39. ----------------- 其他服务自行实现onStart onStop 接口
  40. -- 服务启动 子服务启动需要返回 true
  41. function baseCommand.onStart()
  42. -- log.info("服务启动")
  43. end
  44. -- 服务退出 子服务退出需要返回 true
  45. function baseCommand.onStop()
  46. -- 服务退出
  47. end
  48. -- 更新配置表
  49. function baseCommand.update_config(obj, ...)
  50. -- 由于对战机器人等其他服务是传自身对象作为第一个参数
  51. if type(obj) == "string" then
  52. sharetable.update(obj, ...)
  53. else
  54. sharetable.update(...)
  55. end
  56. end
  57. -- 更新协议
  58. function baseCommand.update_proto()
  59. end
  60. -- 更新逻辑
  61. function baseCommand.update_logic(changeList, params)
  62. -- 由于对战机器人等其他服务是传自身对象作为第一个参数
  63. local fileChangeList = changeList
  64. for key, value in pairs(changeList) do
  65. if type(value) ~= "string" then
  66. fileChangeList = params
  67. break
  68. end
  69. end
  70. hotfixHelper.update(fileChangeList)
  71. end
  72. function baseCommand.exit()
  73. -- 发送服务停止并提出
  74. local addr = skynet.localname(".steward")
  75. local function stop()
  76. if CMD.onStop then
  77. return CMD.onStop()
  78. end
  79. return baseCommand.onStop()
  80. end
  81. if not stop() then
  82. skynet.send(addr, "lua", "stop_service", skynet.self())
  83. end
  84. if skynet.self() ~= addr then
  85. skynet.exit()
  86. end
  87. end
  88. local ti = {}
  89. local function profileCall(cmd, ...)
  90. local func = CMD[cmd]
  91. if not func then
  92. func = baseCommand[cmd]
  93. end
  94. assert(func, cmd .. " not found")
  95. -- local func = assert(CMD[cmd], cmd .. " not found")
  96. profile.start()
  97. local ret
  98. if queueCmds[cmd] or allQueue then
  99. ret = table.pack(cs(func, ...))
  100. else
  101. ret = table.pack(func(...))
  102. end
  103. local time = tonumber(string.format("%0.3f", profile.stop())) * 1000
  104. local p = ti[cmd]
  105. if p == nil then
  106. p = {n = 0, ti = 0}
  107. ti[cmd] = p
  108. end
  109. p.n = p.n + 1
  110. p.ti = p.ti + time
  111. p.max = math.max(p.max or 0, time)
  112. return table.unpack(ret)
  113. end
  114. local function dispatch(session, _, cmd, ...)
  115. if session > 0 then
  116. if not cmdParams then
  117. skynet.retpack(profileCall(cmd, ...))
  118. else
  119. local params = {...}
  120. for i = #cmdParams, 1, -1 do
  121. table.insert(params, 1, cmdParams[i])
  122. end
  123. skynet.retpack(profileCall(cmd, table.unpack(params)))
  124. end
  125. else
  126. if not cmdParams then
  127. profileCall(cmd, ...)
  128. else
  129. local params = {...}
  130. for i = #cmdParams, 1, -1 do
  131. table.insert(params, 1, cmdParams[i])
  132. end
  133. profileCall(cmd, table.unpack(params))
  134. end
  135. end
  136. end
  137. local root = {}
  138. function root.initCmdParams(...)
  139. local temp = {...}
  140. if next(temp) then
  141. cmdParams = temp
  142. end
  143. end
  144. function root.allQueue()
  145. allQueue = true
  146. end
  147. -- 服务别称
  148. local lServiceName
  149. function root.setNickName(name)
  150. lServiceName = name
  151. end
  152. function root.getNickName()
  153. return lServiceName
  154. end
  155. function root.start(commond, serviceName, remote)
  156. CMD = commond
  157. if serviceName then
  158. root.setNickName(serviceName)
  159. end
  160. -- CMD = setmetatable(commond, {__index=baseCommand})
  161. skynet.info_func(
  162. function()
  163. return {mem = collectgarbage("count"), profile = ti}
  164. end
  165. )
  166. skynet.start(
  167. function()
  168. skynet.dispatch("lua", dispatch)
  169. end
  170. )
  171. skynet.init(
  172. function()
  173. if serviceName then
  174. skynet.register(serviceName)
  175. end
  176. local noReport, exitLevel, NoClose = CMD.onStart()
  177. -- 发送服务启动成功
  178. if not noReport then
  179. skynet.send(".steward", "lua", "start_service", skynet.self(), serviceName, remote, exitLevel, NoClose)
  180. end
  181. -- 热更新初始化
  182. local initFlag = (serviceName and serviceName == ".steward")
  183. hotfixHelper.init(initFlag)
  184. end
  185. )
  186. end
  187. return root