node.jsnats.io

nats message queue - ack a message from jetstream consumer in a separate request


Is it possible to manually acknowledge delivered message stream sequence in a separate request (independent on the request receiving the message) to the nats server?

Usually you would receive messages from a consumer, process them and ack them in a single defined context:

    const messages = await consumer.consume({ max_messages: maxMessages });

    for await (const m of messages) {
        //some process logic
        await m.ack();
    }

In my use case I want to bridge http API with a nats stream of messages.
I defined two http endpoints:
- GET /events which would pull messages from a pull consumer.
- POST /events/ack?lastReceivedEventSeqId=10 which would acknowledge with the nats server that the messages up to the message with sequence id 10 have been successfully processed.

The issue is I can not ack a message after I loose the context that initially received the message from nats server.

    //inside implementation of GET /events/ack endpoint`
    const s : Stream | undefined = await jetstream.streams.get('mystream');
    const message = await s.getMessage({seq: 10});
    //message has no `ack` method

Solution

  • In NATS.io JetStream ack is used to let Consumer know that the given message was successfully processed by the client and does not need to be redelivered.

    Consumer is a separate construct on the server that can be treated as a view or a pointer into a Stream. A Stream can have hundreds of Consumers, each going trough messages at its own pace, with its own config, starting sequence, deliver policy etc. And it's Consumers who handle acks for their progress through a Stream.

    If you're using direct get, which is what streams.get() does in the javascript NATS library, it retrieves a message directly from a stream, without a consumer or any additional state on the server side. Hence there is no point in acknowledging it, as Stream does not track progress of going through its messages. You're just getting a single message. You either got it or not. It is enough to check the error of that get operation.