94
vendor/github.com/status-im/status-go/server/timeout.go
generated
vendored
Normal file
94
vendor/github.com/status-im/status-go/server/timeout.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// timeoutManager represents a discrete encapsulation of timeout functionality.
|
||||
// this struct expose 3 functions:
|
||||
// - SetTimeout
|
||||
// - StartTimeout
|
||||
// - StopTimeout
|
||||
type timeoutManager struct {
|
||||
// timeout number of milliseconds the timeout operation will run before executing the `terminate` func()
|
||||
// 0 represents an inactive timeout
|
||||
timeout uint
|
||||
|
||||
// exitQueue handles the cancel signal channels that circumvent timeout operations and prevent the
|
||||
// execution of any `terminate` func()
|
||||
exitQueue *exitQueueManager
|
||||
}
|
||||
|
||||
// newTimeoutManager returns a fully qualified and initialised timeoutManager
|
||||
func newTimeoutManager() *timeoutManager {
|
||||
return &timeoutManager{
|
||||
exitQueue: &exitQueueManager{queue: []chan struct{}{}},
|
||||
}
|
||||
}
|
||||
|
||||
// SetTimeout sets the value of the timeoutManager.timeout
|
||||
func (t *timeoutManager) SetTimeout(milliseconds uint) {
|
||||
t.timeout = milliseconds
|
||||
}
|
||||
|
||||
// StartTimeout starts a timeout operation based on the set timeoutManager.timeout value
|
||||
// the given terminate func() will be executed once the timeout duration has passed
|
||||
func (t *timeoutManager) StartTimeout(terminate func()) {
|
||||
if t.timeout == 0 {
|
||||
return
|
||||
}
|
||||
t.StopTimeout()
|
||||
|
||||
exit := make(chan struct{}, 1)
|
||||
t.exitQueue.add(exit)
|
||||
go t.run(terminate, exit)
|
||||
}
|
||||
|
||||
// StopTimeout terminates a timeout operation and exits gracefully
|
||||
func (t *timeoutManager) StopTimeout() {
|
||||
if t.timeout == 0 {
|
||||
return
|
||||
}
|
||||
t.exitQueue.empty()
|
||||
}
|
||||
|
||||
// run inits the main timeout run function that awaits for the exit command to be triggered or for the
|
||||
// timeout duration to elapse and trigger the parameter terminate function.
|
||||
func (t *timeoutManager) run(terminate func(), exit chan struct{}) {
|
||||
select {
|
||||
case <-exit:
|
||||
return
|
||||
case <-time.After(time.Duration(t.timeout) * time.Millisecond):
|
||||
terminate()
|
||||
// TODO fire signal to let UI know
|
||||
// https://github.com/status-im/status-go/issues/3305
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// exitQueueManager
|
||||
type exitQueueManager struct {
|
||||
queue []chan struct{}
|
||||
queueLock sync.Mutex
|
||||
}
|
||||
|
||||
// add handles new exit channels adding them to the exit queue
|
||||
func (e *exitQueueManager) add(exit chan struct{}) {
|
||||
e.queueLock.Lock()
|
||||
defer e.queueLock.Unlock()
|
||||
|
||||
e.queue = append(e.queue, exit)
|
||||
}
|
||||
|
||||
// empty sends a signal to every exit channel in the queue and then resets the queue
|
||||
func (e *exitQueueManager) empty() {
|
||||
e.queueLock.Lock()
|
||||
defer e.queueLock.Unlock()
|
||||
|
||||
for i := range e.queue {
|
||||
e.queue[i] <- struct{}{}
|
||||
}
|
||||
|
||||
e.queue = []chan struct{}{}
|
||||
}
|
||||
Reference in New Issue
Block a user