mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-26 05:49:25 +01:00
review fixes
* move constant definitions * always give the client at least quitTimeout to respond to ping, even if registerTimeout or quitTimeout are longer than idleTimeout
This commit is contained in:
parent
8910dc59ee
commit
c026cc5ab6
@ -25,12 +25,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RegisterTimeout is how long clients have to register before we disconnect them
|
|
||||||
RegisterTimeout = time.Minute
|
|
||||||
// IdleTimeout is how long without traffic before a registered client is considered idle.
|
|
||||||
IdleTimeout = time.Minute + time.Second*30
|
|
||||||
// QuitTimeout is how long without traffic before an idle client is disconnected
|
|
||||||
QuitTimeout = time.Minute
|
|
||||||
// IdentTimeoutSeconds is how many seconds before our ident (username) check times out.
|
// IdentTimeoutSeconds is how many seconds before our ident (username) check times out.
|
||||||
IdentTimeoutSeconds = 1.5
|
IdentTimeoutSeconds = 1.5
|
||||||
)
|
)
|
||||||
|
@ -9,6 +9,15 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// RegisterTimeout is how long clients have to register before we disconnect them
|
||||||
|
RegisterTimeout = time.Minute
|
||||||
|
// IdleTimeout is how long without traffic before a registered client is considered idle.
|
||||||
|
IdleTimeout = time.Minute + time.Second*30
|
||||||
|
// QuitTimeout is how long without traffic before an idle client is disconnected
|
||||||
|
QuitTimeout = time.Minute
|
||||||
|
)
|
||||||
|
|
||||||
// client idleness state machine
|
// client idleness state machine
|
||||||
|
|
||||||
type TimerState uint
|
type TimerState uint
|
||||||
@ -49,6 +58,7 @@ func NewIdleTimer(client *Client) *IdleTimer {
|
|||||||
// it will eventually be stopped.
|
// it will eventually be stopped.
|
||||||
func (it *IdleTimer) Start() {
|
func (it *IdleTimer) Start() {
|
||||||
it.Lock()
|
it.Lock()
|
||||||
|
it.state = TimerUnregistered
|
||||||
it.lastSeen = time.Now()
|
it.lastSeen = time.Now()
|
||||||
it.Unlock()
|
it.Unlock()
|
||||||
go it.mainLoop()
|
go it.mainLoop()
|
||||||
@ -66,50 +76,47 @@ func (it *IdleTimer) mainLoop() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
registered := client.Registered()
|
idleTime := time.Now().Sub(lastSeen)
|
||||||
now := time.Now()
|
|
||||||
idleTime := now.Sub(lastSeen)
|
|
||||||
newState := state
|
|
||||||
|
|
||||||
switch state {
|
|
||||||
case TimerUnregistered:
|
|
||||||
if registered {
|
|
||||||
// transition to TimerActive state
|
|
||||||
newState = TimerActive
|
|
||||||
}
|
|
||||||
case TimerActive:
|
|
||||||
if idleTime >= IdleTimeout {
|
|
||||||
newState = TimerIdle
|
|
||||||
client.Ping()
|
|
||||||
}
|
|
||||||
case TimerIdle:
|
|
||||||
if idleTime < IdleTimeout {
|
|
||||||
// new ping came in after we transitioned to TimerIdle
|
|
||||||
newState = TimerActive
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
it.Lock()
|
|
||||||
it.state = newState
|
|
||||||
it.Unlock()
|
|
||||||
|
|
||||||
var nextSleep time.Duration
|
var nextSleep time.Duration
|
||||||
switch newState {
|
|
||||||
case TimerUnregistered:
|
if state == TimerUnregistered {
|
||||||
|
if client.Registered() {
|
||||||
|
// transition to active, process new deadlines below
|
||||||
|
state = TimerActive
|
||||||
|
} else {
|
||||||
nextSleep = it.registerTimeout - idleTime
|
nextSleep = it.registerTimeout - idleTime
|
||||||
case TimerActive:
|
}
|
||||||
|
} else if state == TimerIdle {
|
||||||
|
if idleTime < it.quitTimeout {
|
||||||
|
// new ping came in after we transitioned to TimerIdle,
|
||||||
|
// transition back to active and process deadlines below
|
||||||
|
state = TimerActive
|
||||||
|
} else {
|
||||||
|
nextSleep = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if state == TimerActive {
|
||||||
nextSleep = it.idleTimeout - idleTime
|
nextSleep = it.idleTimeout - idleTime
|
||||||
case TimerIdle:
|
if nextSleep <= 0 {
|
||||||
nextSleep = (it.idleTimeout + it.quitTimeout) - idleTime
|
state = TimerIdle
|
||||||
|
client.Ping()
|
||||||
|
// grant the client at least quitTimeout to respond
|
||||||
|
nextSleep = it.quitTimeout
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if nextSleep <= 0 {
|
if nextSleep <= 0 {
|
||||||
// ran out of time, hang them up
|
// ran out of time, hang them up
|
||||||
client.Quit(it.quitMessage(newState))
|
client.Quit(it.quitMessage(state))
|
||||||
client.destroy()
|
client.destroy()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it.Lock()
|
||||||
|
it.state = state
|
||||||
|
it.Unlock()
|
||||||
|
|
||||||
time.Sleep(nextSleep)
|
time.Sleep(nextSleep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user