-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathpatrol_tick.go
120 lines (117 loc) · 2.59 KB
/
patrol_tick.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package patrol
import (
"fmt"
"log"
"sync"
"time"
)
var (
ERR_PATROL_ALREADYRUNNING = fmt.Errorf("Patrol is already running!")
ERR_PATROL_NOTRUNNING = fmt.Errorf("Patrol is NOT running!")
ERR_PATROL_SHUTDOWN = fmt.Errorf("Patrol is Shutdown")
)
func (self *Patrol) Start() error {
self.mu.Lock()
defer self.mu.Unlock()
if self.shutdown {
// patrol is shutdown
return ERR_PATROL_SHUTDOWN
}
if !self.ticker_running.IsZero() {
// ticker running
return ERR_PATROL_ALREADYRUNNING
}
go self.tick()
return nil
}
func (self *Patrol) Stop() error {
self.mu.Lock()
defer self.mu.Unlock()
return self.stop()
}
func (self *Patrol) stop() error {
if self.ticker_running.IsZero() {
// ticker not running
return ERR_PATROL_NOTRUNNING
}
self.ticker_stop = true
return nil
}
func (self *Patrol) tick() {
log.Println("./patrol.tick(): starting")
self.mu.Lock()
if !self.ticker_running.IsZero() {
// ticker is running
self.mu.Unlock()
return
}
if self.shutdown {
// patrol is shutdown
self.mu.Unlock()
return
}
if self.ticker_stop {
// ticker is stopped
self.mu.Unlock()
return
}
self.ticker_running = time.Now()
self.mu.Unlock()
// signal that we've started
if self.config.TriggerStarted != nil {
// since we're not in a lock we're going to wait for this function
self.config.TriggerStarted(self)
}
log.Println("./patrol.tick(): started")
defer func() {
log.Println("./patrol.tick(): stopping")
// signal our trigger we've stopped
// we should signal our trigger before we signal all of our apps
if self.config.TriggerStopped != nil {
// since we're not in a lock we're going to wait for this function
self.config.TriggerStopped(self)
}
// we need to signal to all of our apps/services that we're shutting down!
self.shutdownApps()
self.shutdownServices()
// close our ticker
self.mu.Lock()
self.ticker_stop = false
self.ticker_running = time.Time{}
self.mu.Unlock()
log.Println("./patrol.tick(): stopped")
}()
var wg sync.WaitGroup
for {
// call tick
if self.config.TriggerTick != nil {
self.config.TriggerTick(self)
}
self.mu.RLock()
// if we're shutting down, do not close yet
// we first want to notify our apps/services we're closing
shutdown := self.shutdown
if self.ticker_stop {
self.mu.RUnlock()
// stopped
return
}
self.mu.RUnlock()
// tick
wg.Add(2)
go func() {
defer wg.Done()
self.runApps()
}()
go func() {
defer wg.Done()
self.runServices()
}()
wg.Wait()
if shutdown {
// we're done!
return
}
<-time.After(time.Second * time.Duration(self.config.TickEvery))
}
}