7
7
using Confluent . Kafka ;
8
8
using KafkaFlow . Authentication ;
9
9
using KafkaFlow . Configuration ;
10
+ using KafkaFlow . Extensions ;
10
11
11
12
namespace KafkaFlow . Consumers ;
12
13
13
14
internal class Consumer : IConsumer
14
15
{
15
16
private readonly IDependencyResolver _dependencyResolver ;
16
17
private readonly ILogHandler _logHandler ;
18
+ private readonly bool _stopTheWorldStrategy ;
17
19
18
20
private readonly List < Action < IDependencyResolver , IConsumer < byte [ ] , byte [ ] > , List < TopicPartition > > >
19
21
_partitionsAssignedHandlers = new ( ) ;
@@ -40,6 +42,7 @@ public Consumer(
40
42
this . Configuration = configuration ;
41
43
_flowManager = new ConsumerFlowManager ( this , _logHandler ) ;
42
44
_maxPollIntervalExceeded = new ( _logHandler ) ;
45
+ _stopTheWorldStrategy = Configuration . GetKafkaConfig ( ) . PartitionAssignmentStrategy . IsStopTheWorldStrategy ( ) ;
43
46
44
47
foreach ( var handler in this . Configuration . StatisticsHandlers )
45
48
{
@@ -148,7 +151,17 @@ public void Commit(IReadOnlyCollection<Confluent.Kafka.TopicPartitionOffset> off
148
151
return ;
149
152
}
150
153
151
- _consumer . Commit ( validOffsets ) ;
154
+ if ( _stopTheWorldStrategy )
155
+ {
156
+ _consumer . Commit ( validOffsets ) ;
157
+ }
158
+ else
159
+ {
160
+ foreach ( var topicPartitionOffset in validOffsets )
161
+ {
162
+ _consumer . StoreOffset ( topicPartitionOffset ) ;
163
+ }
164
+ }
152
165
153
166
foreach ( var offset in validOffsets )
154
167
{
@@ -237,17 +250,8 @@ private void EnsureConsumer()
237
250
var kafkaConfig = this . Configuration . GetKafkaConfig ( ) ;
238
251
239
252
var consumerBuilder = new ConsumerBuilder < byte [ ] , byte [ ] > ( kafkaConfig )
240
- . SetPartitionsAssignedHandler (
241
- ( consumer , partitions ) => this . FirePartitionsAssignedHandlers ( consumer , partitions ) )
242
- . SetPartitionsRevokedHandler (
243
- ( consumer , partitions ) =>
244
- {
245
- _partitionsRevokedHandlers . ForEach ( handler => handler ( _dependencyResolver , consumer , partitions ) ) ;
246
- this . Assignment = new List < TopicPartition > ( ) ;
247
- this . Subscription = new List < string > ( ) ;
248
- _currentPartitionsOffsets . Clear ( ) ;
249
- _flowManager . Stop ( ) ;
250
- } )
253
+ . SetPartitionsAssignedHandler ( FirePartitionsAssignedHandlers )
254
+ . SetPartitionsRevokedHandler ( FirePartitionRevokedHandlers )
251
255
. SetErrorHandler ( ( consumer , error ) => _errorsHandlers . ForEach ( x => x ( consumer , error ) ) )
252
256
. SetStatisticsHandler ( ( consumer , statistics ) => _statisticsHandlers . ForEach ( x => x ( consumer , statistics ) ) ) ;
253
257
@@ -293,13 +297,51 @@ private void FirePartitionsAssignedHandlers(
293
297
IConsumer < byte [ ] , byte [ ] > consumer ,
294
298
List < TopicPartition > partitions )
295
299
{
296
- this . Assignment = partitions ;
300
+ if ( _stopTheWorldStrategy )
301
+ {
302
+ this . Assignment = partitions ;
303
+ this . Subscription = consumer . Subscription ;
304
+ _flowManager . Start ( consumer ) ;
305
+ _partitionsAssignedHandlers . ForEach ( handler => handler ( _dependencyResolver , consumer , partitions ) ) ;
306
+ return ;
307
+ }
308
+
309
+ if ( partitions . Count == 0 )
310
+ {
311
+ return ;
312
+ }
313
+
314
+ this . Assignment = this . Assignment . Union ( partitions ) . ToArray ( ) ;
297
315
this . Subscription = consumer . Subscription ;
316
+ _flowManager . Stop ( ) ;
298
317
_flowManager . Start ( consumer ) ;
299
-
300
318
_partitionsAssignedHandlers . ForEach ( handler => handler ( _dependencyResolver , consumer , partitions ) ) ;
301
319
}
302
320
321
+ private void FirePartitionRevokedHandlers ( IConsumer < byte [ ] , byte [ ] > consumer , List < Confluent . Kafka . TopicPartitionOffset > partitions )
322
+ {
323
+ if ( _stopTheWorldStrategy )
324
+ {
325
+ _partitionsRevokedHandlers . ForEach ( handler => handler ( _dependencyResolver , consumer , partitions ) ) ;
326
+ this . Assignment = new List < TopicPartition > ( ) ;
327
+ this . Subscription = new List < string > ( ) ;
328
+ _currentPartitionsOffsets . Clear ( ) ;
329
+ _flowManager . Stop ( ) ;
330
+ return ;
331
+ }
332
+
333
+ this . Assignment = this . Assignment . Except ( partitions . Select ( x => x . TopicPartition ) ) . ToArray ( ) ;
334
+ this . Subscription = consumer . Subscription ;
335
+ foreach ( var partition in partitions )
336
+ {
337
+ _currentPartitionsOffsets . TryRemove ( partition . TopicPartition , out _ ) ;
338
+ }
339
+
340
+ _flowManager . Stop ( ) ;
341
+ _flowManager . Start ( consumer ) ;
342
+ _partitionsRevokedHandlers . ForEach ( handler => handler ( _dependencyResolver , consumer , partitions ) ) ;
343
+ }
344
+
303
345
private void InvalidateConsumer ( )
304
346
{
305
347
_consumer ? . Close ( ) ;
0 commit comments