Browse Source

units can panic and shutdown

master
Chakib Benziane 1 year ago
parent
commit
ba431eb0f1
1 changed files with 45 additions and 2 deletions
  1. 45
    2
      manager.go

+ 45
- 2
manager.go View File

@@ -16,12 +16,15 @@ type WorkUnit interface {
16 16
 type UnitManager interface {
17 17
 	ShouldStop() <-chan bool
18 18
 	Done()
19
+	Panic(err error)
19 20
 }
20 21
 
21 22
 type WorkUnitManager struct {
22 23
 	stop       chan bool
23 24
 	workerQuit chan bool
24 25
 	unit       WorkUnit
26
+	panic      chan error
27
+	isPaniced  bool
25 28
 }
26 29
 
27 30
 func (w *WorkUnitManager) ShouldStop() <-chan bool {
@@ -32,12 +35,21 @@ func (w *WorkUnitManager) Done() {
32 35
 	w.workerQuit <- true
33 36
 }
34 37
 
38
+func (w *WorkUnitManager) Panic(err error) {
39
+	w.panic <- err
40
+	w.isPaniced = true
41
+	w.workerQuit <- true
42
+	close(w.stop)
43
+}
44
+
35 45
 type Manager struct {
36 46
 	signal chan os.Signal
37 47
 
38 48
 	workers map[string]*WorkUnitManager
39 49
 
40 50
 	Quit chan bool
51
+
52
+	panic chan error // Used for panicing goroutines
41 53
 }
42 54
 
43 55
 func (m *Manager) Start() {
@@ -59,7 +71,7 @@ func (m *Manager) Start() {
59 71
 
60 72
 			// send shutdown event to all worker units
61 73
 			for name, w := range m.workers {
62
-				log.Printf("shuting down <%s>\n", name)
74
+				log.Printf("shutting down <%s>\n", name)
63 75
 				w.stop <- true
64 76
 			}
65 77
 
@@ -74,6 +86,35 @@ func (m *Manager) Start() {
74 86
 
75 87
 			m.Quit <- true
76 88
 
89
+			//TODO: wait on Quit signal from any WorkerUnit
90
+		case p := <-m.panic:
91
+			//TODO: refactor shutdown procedure and reuse here
92
+			// send shutdown event to all worker units
93
+
94
+			for name, w := range m.workers {
95
+				if w.isPaniced {
96
+					log.Printf("Panicing for <%s>: %s", name, p)
97
+				}
98
+			}
99
+
100
+			for name, w := range m.workers {
101
+				log.Printf("shuting down <%s>\n", name)
102
+				if !w.isPaniced {
103
+					w.stop <- true
104
+				}
105
+			}
106
+
107
+			// Wait for all units to quit
108
+			for name, w := range m.workers {
109
+				<-w.workerQuit
110
+				log.Printf("<%s> down", name)
111
+			}
112
+
113
+			// All workers have shutdown
114
+			log.Println("All workers have shutdown, shutting down manager ...")
115
+
116
+			m.Quit <- true
117
+
77 118
 		}
78 119
 	}
79 120
 }
@@ -88,6 +129,7 @@ func (m *Manager) AddUnit(unit WorkUnit) {
88 129
 		workerQuit: make(chan bool, 1),
89 130
 		stop:       make(chan bool, 1),
90 131
 		unit:       unit,
132
+		panic:      m.panic,
91 133
 	}
92 134
 
93 135
 	unitType := reflect.TypeOf(unit)
@@ -102,7 +144,8 @@ func (m *Manager) AddUnit(unit WorkUnit) {
102 144
 func NewManager() *Manager {
103 145
 	return &Manager{
104 146
 		signal:  make(chan os.Signal, 1),
105
-		Quit:    make(chan bool),
147
+		Quit:    make(chan bool, 1),
106 148
 		workers: make(map[string]*WorkUnitManager),
149
+		panic:   make(chan error, 1),
107 150
 	}
108 151
 }

Loading…
Cancel
Save