/
poll_state.go
101 lines (77 loc) · 1.99 KB
/
poll_state.go
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
/*
* UpdateHub
* Copyright (C) 2017
* O.S. Systems Sofware LTDA: contato@ossystems.com.br
*
* SPDX-License-Identifier: Apache-2.0
*/
package updatehub
import (
"fmt"
"time"
"github.com/OSSystems/pkg/log"
)
// PollState is the State interface implementation for the UpdateHubStatePoll
type PollState struct {
BaseState
CancellableState
interval time.Duration
ticksCount int64
}
// ID returns the state id
func (state *PollState) ID() UpdateHubState {
return state.id
}
// Cancel cancels a state if it is cancellable
func (state *PollState) Cancel(ok bool, nextState State) bool {
return state.CancellableState.Cancel(ok, nextState)
}
// Handle for PollState encapsulates the polling logic
func (state *PollState) Handle(uh *UpdateHub) (State, bool) {
if !uh.Settings.PollingEnabled && !uh.Settings.ProbeASAP {
state.Wait()
return state.NextState(), false
}
var nextState State
nextState = state
if state.interval < uh.TimeStep {
finalErr := fmt.Errorf("polling interval (%s) must be greater than '%s', using %s instead", state.interval, uh.TimeStep, uh.TimeStep)
log.Warn(finalErr)
state.interval = uh.TimeStep
}
go func() {
ticks := state.ticksCount
polling:
for {
ticker := time.NewTicker(uh.TimeStep)
defer ticker.Stop()
select {
case <-ticker.C:
ticks++
if ticks > 0 && ticks%int64(state.interval.Seconds()/uh.TimeStep.Seconds()) == 0 {
nextState = NewProbeState(uh.DefaultApiClient)
break polling
}
case <-state.cancel:
break
}
}
state.Cancel(true, nextState)
state.ticksCount = ticks
}()
state.Wait()
// state cancelled
if state.NextState() != nil {
return state.NextState(), true
}
return nextState, false
}
// NewPollState creates a new PollState
func NewPollState(pollingInterval time.Duration) *PollState {
state := &PollState{
BaseState: BaseState{id: UpdateHubStatePoll},
CancellableState: CancellableState{cancel: make(chan bool, 1)},
}
state.interval = pollingInterval
return state
}