-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkeepalive.go
More file actions
99 lines (77 loc) · 1.92 KB
/
keepalive.go
File metadata and controls
99 lines (77 loc) · 1.92 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
package ssh
import (
"sync"
"time"
)
type SessionKeepAlive struct {
clientAliveInterval time.Duration
clientAliveCountMax int
ticker *time.Ticker
tickerCh <-chan time.Time
lastReceived time.Time
metrics KeepAliveMetrics
m sync.Mutex
closed bool
}
func NewSessionKeepAlive(clientAliveInterval time.Duration, clientAliveCountMax int) *SessionKeepAlive {
var t *time.Ticker
var tickerCh <-chan time.Time
if clientAliveInterval > 0 {
t = time.NewTicker(clientAliveInterval)
tickerCh = t.C
}
return &SessionKeepAlive{
clientAliveInterval: clientAliveInterval,
clientAliveCountMax: clientAliveCountMax,
ticker: t,
tickerCh: tickerCh,
lastReceived: time.Now(),
}
}
func (ska *SessionKeepAlive) RequestHandlerCallback() {
ska.m.Lock()
ska.metrics.RequestHandlerCalled++
ska.m.Unlock()
ska.Reset()
}
func (ska *SessionKeepAlive) ServerRequestedKeepAliveCallback() {
ska.m.Lock()
defer ska.m.Unlock()
ska.metrics.ServerRequestedKeepAlive++
}
func (ska *SessionKeepAlive) Reset() {
ska.m.Lock()
defer ska.m.Unlock()
ska.metrics.KeepAliveReplyReceived++
if ska.ticker != nil && !ska.closed {
ska.lastReceived = time.Now()
ska.ticker.Reset(ska.clientAliveInterval)
}
}
func (ska *SessionKeepAlive) Ticks() <-chan time.Time {
return ska.tickerCh
}
func (ska *SessionKeepAlive) TimeIsUp() bool {
ska.m.Lock()
defer ska.m.Unlock()
// true: Keep-alive reply not received
return ska.lastReceived.Add(time.Duration(ska.clientAliveCountMax) * ska.clientAliveInterval).Before(time.Now())
}
func (ska *SessionKeepAlive) Close() {
ska.m.Lock()
defer ska.m.Unlock()
if ska.ticker != nil {
ska.ticker.Stop()
}
ska.closed = true
}
func (ska *SessionKeepAlive) Metrics() KeepAliveMetrics {
ska.m.Lock()
defer ska.m.Unlock()
return ska.metrics
}
type KeepAliveMetrics struct {
RequestHandlerCalled int
KeepAliveReplyReceived int
ServerRequestedKeepAlive int
}