CAP icon indicating copy to clipboard operation
CAP copied to clipboard

Why not pull consumer for NATS?

Open geekox86 opened this issue 1 year ago • 7 comments

Greetings,

Out of curiosity, why you did not use a Pull Consumer for NATS since it has better flow control, failure handling, and are more efficient for horizontal scalability?

Regards,

Mohannad

geekox86 avatar Aug 11 '24 18:08 geekox86

Pull Consumer not support queue group

yang-xiaodong avatar Aug 12 '24 02:08 yang-xiaodong

Hi. AFAIK, pull consumers support load balancing over multiple clients consuming from the same consumer; essentially, giving the same Competing Consumers pattern by queue group.

I also asked in the NATS .NET (v2) client library repo, and one of the maintainers mentioned that all their consumers are pull-based now by default.

geekox86 avatar Aug 12 '24 09:08 geekox86

Hi @geekox86 ,

Do you know how to achieve the equivalent behavior of the line of code js.PushSubscribeAsync(subject, groupName, SubscriptionMessageHandler, false, pso); using js.PullSubscribeAsync?

I couldn't find a queue parameter to pass in the PullSubscribeAsync method.

yang-xiaodong avatar Aug 13 '24 01:08 yang-xiaodong

The new API of NATS clients including .NET client go like this:

await using var nats = new NatsConnection();
var js = new NatsJSContext(nats);

// Assuming the pull consumer was created previously like this:
//     var consumer = await js.CreateOrUpdateConsumerAsync(stream: "orders", new ConsumerConfig
//     {
//         Name = "order_processor",
//         DurableName = "order_processor",
//     });
// Running this code by multiple processors will automatically make them competing consumers by NATS.
// I got this information fom https://www.youtube.com/watch?v=_CN1OO7yN0I&list=PLgqCaaYodvKZ0JDTEOryCoJDeLVNvMWpj

var consumer = await js.GetConsumerAsync(stream: "orders", consumer: "order_processor");

await foreach (var msg in consumer.ConsumeAsync<Order>(serializer: orderSerializer).WithCancellation(cancellationToken))
{
    // Process message here

    await msg.AckAsync();
}

Would you consider pull-based consumers?

geekox86 avatar Aug 13 '24 07:08 geekox86

@yang-xiaodong Hi again, just checking of what do you think dear?

geekox86 avatar Aug 18 '24 05:08 geekox86

@geekox86 This requires migrating the NATS client library to v2 first, would you be willing to submit a PR?

yang-xiaodong avatar Aug 18 '24 07:08 yang-xiaodong

Note: Waiting for Nats.net client to implement push-based consumers, pull-based consumers do not support fanout.

https://github.com/nats-io/nats.net/issues/686

yang-xiaodong avatar Dec 04 '24 13:12 yang-xiaodong

Hi @geekox86 ,

Do you know how to achieve the equivalent behavior of the line of code js.PushSubscribeAsync(subject, groupName, SubscriptionMessageHandler, false, pso); using js.PullSubscribeAsync?

I couldn't find a queue parameter to pass in the PullSubscribeAsync method.

是不是我的理解有误,如果使用 Push模式并且加了groupName这个参数后,相当于使用了队列模式,这样子的话队列里的消费者只会有一个消费者处理消息,达不到扇出的效果了?

lable avatar Oct 28 '25 00:10 lable