-- agent池 local skynet = require "skynet" local root = class("agentPool") function root:ctor(agentService, count) self.objs = {} self.init = count or 4 -- 自增服务数量 self.agentService = agentService -- 生成agent self:new_agent_services(self.init) end -- 创建agent服务 function root:new_agent_service(agentCount) local addr = skynet.newservice(self.agentService) return {addr = addr, max = agentCount or 50, used = 0} end -- 创建一批agent服务 function root:new_agent_services(count) local list = {} for i = 1, count do local agentInfo = self:new_agent_service() table.insert(self.objs, agentInfo) table.insert(list, agentInfo) end return list end -- 获取可用agent服务列表 function root:get_agent_srv_list() -- 没有现成可用的,创建新的 local list = {} for _, v in ipairs(self.objs) do if v.used < v.max then table.insert(list, v) end end if is_empty(list) then -- agent服务不够 list = self:new_agent_services(self.init) end return list end -- 获取agent地址列表 function root:get_agent_srv_addr_list() local list = {} for k, v in pairs(self.objs) do table.insert(list, v.addr) end return list end -- 获取agent服务信息 function root:get_agent_info_by_addr(addr) for k, v in pairs(self.objs) do if addr == v.addr then return v end end end -- 分配 function root:alloc_agent_srv() local list = self:get_agent_srv_list() local id = math.random(1, #list) local obj = list[id] return obj.addr end -- 绑定 function root:bind_agent(id, addr) local agentInfo = self:get_agent_info_by_addr(addr) if is_empty(agentInfo) then return false end agentInfo.used = agentInfo.used + 1 agentInfo.bindTime = skynet_time() return true end -- 解绑 function root:unbind_agent(id, addr) local agentInfo = self:get_agent_info_by_addr(addr) if is_empty(agentInfo) then return false end agentInfo.used = math.max(agentInfo.used - 1, 0) agentInfo.unbindTime = skynet_time() -- 回收不活跃agent服务 self:recycle_agent_service() return true end -- 一次最多回收10个agent function root:recycle_agent_service() if #self.objs <= 5 then return end local list = {} local nowTime = skynet_time() for index, v in ipairs(self.objs) do -- 超过一小时未被使用 if v.used <= 0 and v.bindTime and v.unbindTime and v.unbindTime >= v.bindTime and nowTime - v.unbindTime >= 3600 then table.insert(list, index) end end if #self.objs <= 0 then return end for i = 10, 1, -1 do local index = list[i] if index then local addr = self.objs[index].addr table.remove(self.objs, index) skynet.send(addr, "lua", "recycle") end end end -- 移除agent服务 function root:remove_agent_service(addr) for k, v in pairs(self.objs) do if v.addr == addr then table.remove(self.objs, k) return true end end return false end -- 当前活跃agent服务数 function root:get_agent_service_count() return #self.objs end return root