Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recieved messages automatically ack-ed #20

Open
jfmesse opened this issue Feb 9, 2021 · 3 comments
Open

Recieved messages automatically ack-ed #20

jfmesse opened this issue Feb 9, 2021 · 3 comments

Comments

@jfmesse
Copy link

jfmesse commented Feb 9, 2021

Hi,

With the way the Listener class is configured, upon receiving a message it immediately performs an ack() on the message before the message handler has been called:

    const onMessage = (msg) => {
      msg.ack();
      return onMessageCallback(msg);
    };

This is effectively telling the pubsub queue that the message has been successfully handled/processed, and that the topic can move on.

However most use cases of message processing involve an asynchronous activity (e.g. writing to another queue or database). By having the ack() performed immediately, this means that a failure during processing the item (e.g. database down, node process crashed) would effectively mean the message could have been lost, as the library has already performed the ack() and the pubsub queue has moved on.

By immediately ack-ing, it also removes any flow control from the client. The Listener is saying the client is ready for more, but the client could have an ever growing number of async message processing jobs still in-flight.

In these scenarios, I would have thought the ack() call is surely more appropriate after the message processing has completed, but the Listener class does not provide such a way to do this.

My suggestions for possible implementations are:

  • async or callback message handlers that upon successful completion, onMessage then acks
  • leave ack-ing up to the onMessageCallback function (the ack() method is available as the msg object is passed through as the param)

With such a setup, it removes the risk of the topic moving on without the client successfully performing its activity on the message.

A simple implementation with a callback approach could look something like:

const onMessage = (msg) => {
  onMessageCallback(msg, err => {
    if (!err) {
      msg.ack();
    } else { // some failure handling
      console.err(err);
      msg.nack();
    }
  });
};

The API could be updated in a way to make it backward compatible (e.g. additional param indicating it is async/wants to control message ack-ing).

Does this seem reasonable?

@zakagan
Copy link
Collaborator

zakagan commented Feb 10, 2021

Hi,

We have an async listener for our Python client, see here. I will look into adding this for the JS client as well

@zakagan
Copy link
Collaborator

zakagan commented Apr 12, 2021

I have a first pass for a solution, can you take a look and provide any feedback? #24 @jfmesse

@jfmesse
Copy link
Author

jfmesse commented Apr 15, 2021

I have a first pass for a solution, can you take a look and provide any feedback? #24 @jfmesse

@zakagan sorry just seen this. I've supplied some feedback on the PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants