agent_util.lua
2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
local _M = { }
-- 超时次数
local heartTimeoutCount = 0
-- 加速次数
local heartQuickCount = 0
-- 上次检查心跳时间
local lastHeartCheckTime = 0
-- 下次进入定时检查的时间
local nextCheckTime = 0
-- 心跳误差允许范围
local HEART_BEAT_ERROR_LIMIT = 1
-- 最大超时次数
local HEART_TIMEOUT_COUNT_MAX = 20
-- 最大加速次数
local HEART_QUICK_COUNT_MAX = 5
-- 心跳定时间隔
local HEART_TIMER_INTERVAL = 5
local function check_heart_beat(agent, now)
-- 充值等操作不检查心跳
local role = agent.role
if role.ignoreHeartbeat then
lastHeartCheckTime = now - HEART_TIMER_INTERVAL
heartTimeoutCount = 0
return
end
if lastHeartCheckTime - now > HEART_TIMER_INTERVAL or
now - lastHeartCheckTime > HEART_TIMER_INTERVAL then
heartTimeoutCount = heartTimeoutCount + 1
if heartTimeoutCount >= HEART_TIMEOUT_COUNT_MAX then
skynet.error("timeout! then agent will shut down by self", agent.client_fd, role:getProperty("name"), role:getProperty("id"))
skynet.call(agent.gate_serv, "lua", "kick", agent.client_fd)
heartTimeoutCount = 0
end
else
heartTimeoutCount = 0
end
end
local PointDataMark = {}
local resetTimeStr = string.format("%02d00", RESET_TIME)
local function check_daily_reset(agent, now)
local date = os.date("*t", now)
local timeStr = string.format("%02d%02d", date.hour, date.min)
local dataStr = date.year .. string.format("%02d", date.month) .. string.format("%02d", date.day)
local function timeEffect(checkTimeStr)
if timeStr ~= checkTimeStr then
return false
end
if PointDataMark[dataStr] and PointDataMark[dataStr][checkTimeStr] then
return false
end
PointDataMark[dataStr] = PointDataMark[dataStr] or {}
PointDataMark[dataStr][checkTimeStr] = true
return true
end
if timeEffect(resetTimeStr) then
-- 刷新每日数据
local role = agent.role
if role then
role:onCrossDay(now, true)
end
end
end
function _M:update(agent)
local now = skynet.timex()
local role = agent.role
if now >= nextCheckTime then
pcall(check_heart_beat, agent, now)
nextCheckTime = now + HEART_TIMER_INTERVAL
end
pcall(check_daily_reset, agent, now)
pcall(role.onRecoverTimer, role, now)
end
function _M:heart_beat(agent)
local now = skynet.timex()
if now == lastHeartCheckTime then
return
end
if now - lastHeartCheckTime <= HEART_TIMER_INTERVAL - HEART_BEAT_ERROR_LIMIT then
heartQuickCount = heartQuickCount + 1
if heartQuickCount == HEART_QUICK_COUNT_MAX then
-- 将错误写入日志
local role = agent.role
skynet.error("Warning, heart beating is too quick, shut down the agent", agent.client_fd, role:getProperty("name"), role:getProperty("id"))
-- skynet.call(agent.gate_serv, "lua", "kick", agent.client_fd)
role:warningHeartTooQuick()
heartQuickCount = 0
end
else
heartQuickCount = 0
end
lastHeartCheckTime = now
end
function _M:reset()
heartTimeoutCount = 0
heartQuickCount = 0
lastHeartCheckTime = skynet.timex()
end
return _M