@@ -40,6 +40,7 @@ type ConsumerOffset struct {
40
40
lastOffsetCommit time.Time
41
41
offsets map [int32 ]kafka.Offset
42
42
stopCh chan bool
43
+ stoppedCh chan bool
43
44
}
44
45
45
46
// Define a Dispatcher Struct to hold Dispatcher Config and dispatcher implementation details
@@ -62,17 +63,19 @@ func NewDispatcher(dispatcherConfig DispatcherConfig) *Dispatcher {
62
63
return dispatcher
63
64
}
64
65
65
- // Close The Running Consumers Connections
66
+ // Stop All Consumers
66
67
func (d * Dispatcher ) StopConsumers () {
67
68
for subscription , _ := range d .consumers {
68
69
d .stopConsumer (subscription )
69
70
}
70
71
}
71
72
73
+ // Stop An Individual Consumer
72
74
func (d * Dispatcher ) stopConsumer (subscription Subscription ) {
73
75
d .Logger .Info ("Stopping Consumer" , zap .String ("GroupId" , subscription .GroupId ), zap .String ("topic" , d .Topic ), zap .String ("URI" , subscription .URI ))
74
-
75
- d .consumers [subscription ].stopCh <- true
76
+ consumerOffset := d .consumers [subscription ]
77
+ consumerOffset .stopCh <- true // Send Stop Signal
78
+ <- consumerOffset .stoppedCh // Wait Until Stop Completes
76
79
delete (d .consumers , subscription )
77
80
}
78
81
@@ -94,8 +97,14 @@ func (d *Dispatcher) initConsumer(subscription Subscription) (*ConsumerOffset, e
94
97
return nil , err
95
98
}
96
99
97
- stopCh := make (chan bool )
98
- consumerOffset := ConsumerOffset {consumer : consumer , lastOffsetCommit : time .Now (), offsets : make (map [int32 ]kafka.Offset ), stopCh : stopCh }
100
+ // Create The ConsumerOffset For Tracking State
101
+ consumerOffset := ConsumerOffset {
102
+ consumer : consumer ,
103
+ lastOffsetCommit : time .Now (),
104
+ offsets : make (map [int32 ]kafka.Offset ),
105
+ stopCh : make (chan bool ),
106
+ stoppedCh : make (chan bool ),
107
+ }
99
108
100
109
// Start Consuming Messages From Topic (Async)
101
110
go d .handleKafkaMessages (consumerOffset , subscription )
@@ -110,23 +119,26 @@ func (d *Dispatcher) handleKafkaMessages(consumerOffset ConsumerOffset, subscrip
110
119
// Configure The Logger
111
120
logger := d .Logger .With (zap .String ("GroupID" , subscription .GroupId ))
112
121
113
- stopped := false
114
122
// Message Processing Loop
123
+ stopped := false
115
124
for ! stopped {
116
125
117
126
// Poll For A New Event Message Until We Get One (Timeout is how long to wait before requesting again)
118
127
event := consumerOffset .consumer .Poll (d .PollTimeoutMillis )
119
128
120
129
select {
121
- // Handle Shutdown Case
130
+
131
+ // Non-Blocking Channel Check
122
132
case <- consumerOffset .stopCh :
123
- stopped = true
133
+ stopped = true // Handle Shutdown Case - Break Out Of Loop
134
+
124
135
default :
125
136
137
+ // No Events To Process At The Moment
126
138
if event == nil {
139
+
127
140
// Commit Offsets If The Amount Of Time Since Last Commit Is "OffsetCommitDuration" Or More
128
141
currentTimeDuration := time .Now ().Sub (consumerOffset .lastOffsetCommit )
129
-
130
142
if currentTimeDuration > d .OffsetCommitDurationMinimum && currentTimeDuration >= d .OffsetCommitDuration {
131
143
d .commitOffsets (logger , & consumerOffset )
132
144
}
@@ -177,12 +189,17 @@ func (d *Dispatcher) handleKafkaMessages(consumerOffset ConsumerOffset, subscrip
177
189
}
178
190
}
179
191
192
+ // Commit Offsets One Last Time
193
+ logger .Debug ("Final Offset Commit" )
194
+ d .commitOffsets (logger , & consumerOffset )
195
+
180
196
// Safe To Shutdown The Consumer
181
197
logger .Debug ("Shutting Down Consumer" )
182
198
err := consumerOffset .consumer .Close ()
183
199
if err != nil {
184
200
logger .Error ("Unable To Stop Consumer" , zap .Error (err ))
185
201
}
202
+ consumerOffset .stoppedCh <- true
186
203
}
187
204
188
205
// Store Updated Offsets For The Partition If Consumer Still Has It Assigned
@@ -213,6 +230,7 @@ func (d *Dispatcher) commitOffsets(logger *zap.Logger, consumerOffset *ConsumerO
213
230
consumerOffset .lastOffsetCommit = time .Now ()
214
231
}
215
232
233
+ // Update The Dispatcher's Subscriptions
216
234
func (d * Dispatcher ) UpdateSubscriptions (subscriptions []Subscription ) map [Subscription ]error {
217
235
218
236
failedSubscriptions := make (map [Subscription ]error )
0 commit comments