-- 管家服务 require "skynet.manager" local skynet = require "skynet" local cluster = require "skynet.cluster" local codecache = require "skynet.codecache" local nodeUtil = require("utils.nodeUtil") local nodes = require("nodes") local baseService = require("baseService") local hotfixHelper = require("hotfix.helper") local SERVICES = {} local root = {} local clusterName = skynet.getenv("clusterName") local nodeName = skynet.getenv("nodeName") -- 服务退出 local function l_service_exit() if #SERVICES > 0 then local needWait for _, v in ipairs(SERVICES) do if not v.NoClose then needWait = true skynet.send(v.addr, "lua", "exit") end end if needWait then return end end -- 服务全部退出 进程关闭 skynet.abort() end -- 服务 - 开启 function root.start_service(addr, name, remote, exitLevel, NoClose) table.insert(SERVICES, {addr = addr, name = name, exitLevel = exitLevel or 1, NoClose = NoClose}) if remote then cluster.register(name, addr) end end -- 服务 - 停止 function root.stop_service(addr) local sindex, exitLevel = nil, nil for k, v in ipairs(SERVICES) do if v.addr == addr then sindex = k exitLevel = v.exitLevel end end if not sindex then return end table.remove(SERVICES, sindex) local sameLevelExit = true for _, v in ipairs(SERVICES) do if v.exitLevel == exitLevel and not v.NoClose then sameLevelExit = false break end end if not sameLevelExit then return end -- 同等级都退出了,再退出下一个等级的服务 l_service_exit() end -- 更新配置表 function root.update_config() codecache.clear() local addr = skynet.localname(".config") if not addr then return end local files = skynet.call(".config", "lua", "get_update_files") if not files then return end -- 向非配置服务发送更新配置表请求 for _, v in ipairs(SERVICES) do if v.name ~= ".config" then skynet.send(v.addr, "lua", "update_config", table.unpack(files)) end end end -- 更新协议 function root.update_proto() codecache.clear() local addr = skynet.localname(".srvProtoLoad") if not addr then return end skynet.call(".srvProtoLoad", "lua", "update_proto") local currAddr = skynet.self() for _, v in ipairs(SERVICES) do if v.addr ~= currAddr then skynet.send(v.addr, "lua", "update_proto") end end end -- 更新逻辑 function root.update_logic() codecache.clear() local files = hotfixHelper.getChanggeFiles() if table.empty(files) then return end local currAddr = skynet.self() for _, v in ipairs(SERVICES) do if v.addr ~= currAddr then skynet.send(v.addr, "lua", "update_logic", files) end end end -- 更新所有 function root.update() root.update_config() root.update_logic() root.update_proto() end function root.exit() -- 退出优先级 退出等级小, 服务地址大 table.sort( SERVICES, function(a, b) if a.exitLevel == b.exitLevel then return a.addr > b.addr end return a.exitLevel < b.exitLevel end ) l_service_exit() end function root.onStart() return true end -- 心跳 function root.node_hb_to_master(nodeMaster) if nodes[nodeName] == nil then return end nodeMaster = nodeMaster or "master" local nodeInfo = table.copy(nodes[nodeName]) nodeInfo.clusterName = clusterName nodeInfo.nodeName = nodeName skynet.fork( function(...) while true do nodeUtil:send_to_node(nodeMaster, ".srvNodeMgr", "node_heart_beat", nodeInfo) skynet.sleep(5 * 100) end end ) end baseService.start(root, ".steward", true)