|
@@ -38,7 +38,6 @@ type IdleTimer struct {
|
38
|
38
|
|
39
|
39
|
// mutable
|
40
|
40
|
client *Client
|
41
|
|
- state TimerState
|
42
|
41
|
lastSeen time.Time
|
43
|
42
|
}
|
44
|
43
|
|
|
@@ -49,7 +48,6 @@ func NewIdleTimer(client *Client) *IdleTimer {
|
49
|
48
|
idleTimeout: IdleTimeout,
|
50
|
49
|
quitTimeout: QuitTimeout,
|
51
|
50
|
client: client,
|
52
|
|
- state: TimerUnregistered,
|
53
|
51
|
}
|
54
|
52
|
return &it
|
55
|
53
|
}
|
|
@@ -58,17 +56,18 @@ func NewIdleTimer(client *Client) *IdleTimer {
|
58
|
56
|
// it will eventually be stopped.
|
59
|
57
|
func (it *IdleTimer) Start() {
|
60
|
58
|
it.Lock()
|
61
|
|
- it.state = TimerUnregistered
|
62
|
59
|
it.lastSeen = time.Now()
|
63
|
60
|
it.Unlock()
|
64
|
61
|
go it.mainLoop()
|
65
|
62
|
}
|
66
|
63
|
|
67
|
64
|
func (it *IdleTimer) mainLoop() {
|
|
65
|
+ state := TimerUnregistered
|
|
66
|
+ var lastPinged time.Time
|
|
67
|
+
|
68
|
68
|
for {
|
69
|
69
|
it.Lock()
|
70
|
70
|
client := it.client
|
71
|
|
- state := it.state
|
72
|
71
|
lastSeen := it.lastSeen
|
73
|
72
|
it.Unlock()
|
74
|
73
|
|
|
@@ -76,7 +75,8 @@ func (it *IdleTimer) mainLoop() {
|
76
|
75
|
return
|
77
|
76
|
}
|
78
|
77
|
|
79
|
|
- idleTime := time.Now().Sub(lastSeen)
|
|
78
|
+ now := time.Now()
|
|
79
|
+ idleTime := now.Sub(lastSeen)
|
80
|
80
|
var nextSleep time.Duration
|
81
|
81
|
|
82
|
82
|
if state == TimerUnregistered {
|
|
@@ -87,8 +87,8 @@ func (it *IdleTimer) mainLoop() {
|
87
|
87
|
nextSleep = it.registerTimeout - idleTime
|
88
|
88
|
}
|
89
|
89
|
} else if state == TimerIdle {
|
90
|
|
- if idleTime < it.quitTimeout {
|
91
|
|
- // new ping came in after we transitioned to TimerIdle,
|
|
90
|
+ if lastSeen.After(lastPinged) {
|
|
91
|
+ // new pong came in after we transitioned to TimerIdle,
|
92
|
92
|
// transition back to active and process deadlines below
|
93
|
93
|
state = TimerActive
|
94
|
94
|
} else {
|
|
@@ -100,6 +100,7 @@ func (it *IdleTimer) mainLoop() {
|
100
|
100
|
nextSleep = it.idleTimeout - idleTime
|
101
|
101
|
if nextSleep <= 0 {
|
102
|
102
|
state = TimerIdle
|
|
103
|
+ lastPinged = now
|
103
|
104
|
client.Ping()
|
104
|
105
|
// grant the client at least quitTimeout to respond
|
105
|
106
|
nextSleep = it.quitTimeout
|
|
@@ -113,10 +114,6 @@ func (it *IdleTimer) mainLoop() {
|
113
|
114
|
return
|
114
|
115
|
}
|
115
|
116
|
|
116
|
|
- it.Lock()
|
117
|
|
- it.state = state
|
118
|
|
- it.Unlock()
|
119
|
|
-
|
120
|
117
|
time.Sleep(nextSleep)
|
121
|
118
|
}
|
122
|
119
|
}
|