@@ -22,9 +22,12 @@ import (
22
22
"fmt"
23
23
"math/rand"
24
24
"strconv"
25
+ "strings"
25
26
"sync"
26
27
"time"
27
28
29
+ "github.com/apache/pulsar-client-go/pulsaradmin/pkg/utils"
30
+
28
31
"github.com/apache/pulsar-client-go/pulsar/crypto"
29
32
"github.com/apache/pulsar-client-go/pulsar/internal"
30
33
pb "github.com/apache/pulsar-client-go/pulsar/internal/pulsar_proto"
@@ -81,6 +84,10 @@ func newConsumer(client *client, options ConsumerOptions) (Consumer, error) {
81
84
options .ReceiverQueueSize = defaultReceiverQueueSize
82
85
}
83
86
87
+ if options .EnableZeroQueueConsumer {
88
+ options .ReceiverQueueSize = 0
89
+ }
90
+
84
91
if options .Interceptors == nil {
85
92
options .Interceptors = defaultConsumerInterceptors
86
93
}
@@ -236,7 +243,24 @@ func newConsumer(client *client, options ConsumerOptions) (Consumer, error) {
236
243
}
237
244
238
245
func newInternalConsumer (client * client , options ConsumerOptions , topic string ,
239
- messageCh chan ConsumerMessage , dlq * dlqRouter , rlq * retryRouter , disableForceTopicCreation bool ) (* consumer , error ) {
246
+ messageCh chan ConsumerMessage , dlq * dlqRouter , rlq * retryRouter , disableForceTopicCreation bool ) (Consumer , error ) {
247
+ partitions , err := client .TopicPartitions (topic )
248
+ if err != nil {
249
+ return nil , err
250
+ }
251
+
252
+ if len (partitions ) > 1 && options .EnableZeroQueueConsumer {
253
+ return nil , pkgerrors .New ("ZeroQueueConsumer is not supported for partitioned topics" )
254
+ }
255
+
256
+ if len (partitions ) == 1 && options .EnableZeroQueueConsumer &&
257
+ strings .Contains (partitions [0 ], utils .PARTITIONEDTOPICSUFFIX ) {
258
+ return nil , pkgerrors .New ("ZeroQueueConsumer is not supported for partitioned topics" )
259
+ }
260
+
261
+ if len (partitions ) == 1 && options .EnableZeroQueueConsumer {
262
+ return newZeroConsumer (client , options , topic , messageCh , dlq , rlq , disableForceTopicCreation )
263
+ }
240
264
241
265
consumer := & consumer {
242
266
topic : topic ,
@@ -253,7 +277,7 @@ func newInternalConsumer(client *client, options ConsumerOptions, topic string,
253
277
metrics : client .metrics .GetLeveledMetrics (topic ),
254
278
}
255
279
256
- err : = consumer .internalTopicSubscribeToPartitions ()
280
+ err = consumer .internalTopicSubscribeToPartitions ()
257
281
if err != nil {
258
282
return nil , err
259
283
}
@@ -343,10 +367,6 @@ func (c *consumer) internalTopicSubscribeToPartitions() error {
343
367
consumer * partitionConsumer
344
368
}
345
369
346
- receiverQueueSize := c .options .ReceiverQueueSize
347
- metadata := c .options .Properties
348
- subProperties := c .options .SubscriptionProperties
349
-
350
370
startPartition := oldNumPartitions
351
371
partitionsToAdd := newNumPartitions - oldNumPartitions
352
372
@@ -364,45 +384,7 @@ func (c *consumer) internalTopicSubscribeToPartitions() error {
364
384
365
385
go func (idx int , pt string ) {
366
386
defer wg .Done ()
367
-
368
- var nackRedeliveryDelay time.Duration
369
- if c .options .NackRedeliveryDelay == 0 {
370
- nackRedeliveryDelay = defaultNackRedeliveryDelay
371
- } else {
372
- nackRedeliveryDelay = c .options .NackRedeliveryDelay
373
- }
374
- opts := & partitionConsumerOpts {
375
- topic : pt ,
376
- consumerName : c .consumerName ,
377
- subscription : c .options .SubscriptionName ,
378
- subscriptionType : c .options .Type ,
379
- subscriptionInitPos : c .options .SubscriptionInitialPosition ,
380
- partitionIdx : idx ,
381
- receiverQueueSize : receiverQueueSize ,
382
- nackRedeliveryDelay : nackRedeliveryDelay ,
383
- nackBackoffPolicy : c .options .NackBackoffPolicy ,
384
- metadata : metadata ,
385
- subProperties : subProperties ,
386
- replicateSubscriptionState : c .options .ReplicateSubscriptionState ,
387
- startMessageID : c .options .startMessageID ,
388
- startMessageIDInclusive : c .options .StartMessageIDInclusive ,
389
- subscriptionMode : c .options .SubscriptionMode ,
390
- readCompacted : c .options .ReadCompacted ,
391
- interceptors : c .options .Interceptors ,
392
- maxReconnectToBroker : c .options .MaxReconnectToBroker ,
393
- backoffPolicy : c .options .BackoffPolicy ,
394
- keySharedPolicy : c .options .KeySharedPolicy ,
395
- schema : c .options .Schema ,
396
- decryption : c .options .Decryption ,
397
- ackWithResponse : c .options .AckWithResponse ,
398
- maxPendingChunkedMessage : c .options .MaxPendingChunkedMessage ,
399
- expireTimeOfIncompleteChunk : c .options .ExpireTimeOfIncompleteChunk ,
400
- autoAckIncompleteChunk : c .options .AutoAckIncompleteChunk ,
401
- consumerEventListener : c .options .EventListener ,
402
- enableBatchIndexAck : c .options .EnableBatchIndexAcknowledgment ,
403
- ackGroupingOptions : c .options .AckGroupingOptions ,
404
- autoReceiverQueueSize : c .options .EnableAutoScaledReceiverQueueSize ,
405
- }
387
+ opts := newPartitionConsumerOpts (pt , c .consumerName , idx , c .options )
406
388
cons , err := newPartitionConsumer (c , c .client , opts , c .messageCh , c .dlq , c .metrics )
407
389
ch <- ConsumerError {
408
390
err : err ,
@@ -444,6 +426,48 @@ func (c *consumer) internalTopicSubscribeToPartitions() error {
444
426
return nil
445
427
}
446
428
429
+ func newPartitionConsumerOpts (topic , consumerName string , idx int , options ConsumerOptions ) * partitionConsumerOpts {
430
+
431
+ var nackRedeliveryDelay time.Duration
432
+ if options .NackRedeliveryDelay == 0 {
433
+ nackRedeliveryDelay = defaultNackRedeliveryDelay
434
+ } else {
435
+ nackRedeliveryDelay = options .NackRedeliveryDelay
436
+ }
437
+ return & partitionConsumerOpts {
438
+ topic : topic ,
439
+ consumerName : consumerName ,
440
+ subscription : options .SubscriptionName ,
441
+ subscriptionType : options .Type ,
442
+ subscriptionInitPos : options .SubscriptionInitialPosition ,
443
+ partitionIdx : idx ,
444
+ receiverQueueSize : options .ReceiverQueueSize ,
445
+ nackRedeliveryDelay : nackRedeliveryDelay ,
446
+ nackBackoffPolicy : options .NackBackoffPolicy ,
447
+ metadata : options .Properties ,
448
+ subProperties : options .SubscriptionProperties ,
449
+ replicateSubscriptionState : options .ReplicateSubscriptionState ,
450
+ startMessageID : options .startMessageID ,
451
+ startMessageIDInclusive : options .StartMessageIDInclusive ,
452
+ subscriptionMode : options .SubscriptionMode ,
453
+ readCompacted : options .ReadCompacted ,
454
+ interceptors : options .Interceptors ,
455
+ maxReconnectToBroker : options .MaxReconnectToBroker ,
456
+ backoffPolicy : options .BackoffPolicy ,
457
+ keySharedPolicy : options .KeySharedPolicy ,
458
+ schema : options .Schema ,
459
+ decryption : options .Decryption ,
460
+ ackWithResponse : options .AckWithResponse ,
461
+ maxPendingChunkedMessage : options .MaxPendingChunkedMessage ,
462
+ expireTimeOfIncompleteChunk : options .ExpireTimeOfIncompleteChunk ,
463
+ autoAckIncompleteChunk : options .AutoAckIncompleteChunk ,
464
+ consumerEventListener : options .EventListener ,
465
+ enableBatchIndexAck : options .EnableBatchIndexAcknowledgment ,
466
+ ackGroupingOptions : options .AckGroupingOptions ,
467
+ autoReceiverQueueSize : options .EnableAutoScaledReceiverQueueSize ,
468
+ }
469
+ }
470
+
447
471
func (c * consumer ) Subscription () string {
448
472
return c .options .SubscriptionName
449
473
}
0 commit comments