Window size(prefetch) control of unacknowledged message in Node.js

devtony
devtony Member Posts: 2

The messages in our system need to be processed in sequential (we expect the message to be handled one after another) and we are trying to build a queue consumer with the liberary solclientjs. (https://www.npmjs.com/package/solclientjs)

I read some blogs and posts that mentioned two keywords the flow windowSize and MAX_UNACKNOWLEDGED_MESSSAGES.

fristly, I have tried to reduce the windowSize to 1 and leave the MAX_DELIVERED_UNACKNOWLEDGED_MSGS_PER_FLOW as default with below sample code and saw the incoming messages are processed almost sententiously.

// consumer generation logic
this.messageConsumer = this.session.createMessageConsumer({
    queueDescriptor: new QueueDescriptor({
        name: this.consumerOptions?.queueName as string,
        type: QueueType.QUEUE
    }),
    acknowledgeMode: MessageConsumerAcknowledgeMode.CLIENT,
    activeIndicationEnabled: true,
    windowSize: 1 // set the windownSize here
});

// process logic
// have noticed that the handler function is not async/Promise by the typscript definition
//
// [solace.MessageConsumerEventName.MESSAGE]: (
//     message: solace.Message
// ) => void;

this.messageConsumer?.on(MessageConsumerEventName.MESSAGE, async (message) => {
    const messageBody = this.decoder.decode(message.getBinaryAttachment());
    const sleepInSec = _.random(5, 10);
    logger.info(`${messageBody} arrived, simulate process ${sleepInSec}s`);
    await sleep(sleepInSec * 1000);
    message.acknowledge();
    logger.info(`${messageBody} acknowledged`);
});

// log

[2022-03-30T16:48:00.021Z] [info]: message[0] arrived, simulate process 6s

[2022-03-30T16:48:00.028Z] [info]: message[1] arrived, simulate process 8s

[2022-03-30T16:48:00.033Z] [info]: message[2] arrived, simulate process 5s

[2022-03-30T16:48:00.046Z] [info]: message[3] arrived, simulate process 8s

[2022-03-30T16:48:00.061Z] [info]: message[4] arrived, simulate process 5s

[2022-03-30T16:48:05.048Z] [info]: message[2] acknowledged

[2022-03-30T16:48:05.064Z] [info]: message[4] acknowledged

[2022-03-30T16:48:06.028Z] [info]: message[0] acknowledged

[2022-03-30T16:48:08.044Z] [info]: message[1] acknowledged

[2022-03-30T16:48:08.059Z] [info]: message[3] acknowledged

additionally I adjusted the MAX_DELIVERED_UNACKNOWLEDGED_MSGS_PER_FLOW to 1 in the queue config, then looks the consumer behavior is expected.

// log

[2022-03-30T17:34:04.099Z] [info]: message[0] arrived, simulate process 9s

[2022-03-30T17:34:13.101Z] [info]: message[0] acknowledged

[2022-03-30T17:34:14.111Z] [info]: message[1] arrived, simulate process 5s

[2022-03-30T17:34:19.117Z] [info]: message[1] acknowledged

[2022-03-30T17:34:20.127Z] [info]: message[2] arrived, simulate process 9s

[2022-03-30T17:34:29.137Z] [info]: message[2] acknowledged

[2022-03-30T17:34:30.149Z] [info]: message[3] arrived, simulate process 6s

[2022-03-30T17:34:36.154Z] [info]: message[3] acknowledged

[2022-03-30T17:34:37.168Z] [info]: message[4] arrived, simulate process 9s

[2022-03-30T17:34:46.185Z] [info]: message[4] acknowledged

And I feel like it is not a recommended to do this by adjust the MAX_UNACKNOWLEDGED_MESSAGES setting.

https://solace.community/discussion/comment/3681#Comment_3681

It is not flow control. Withholding acknowledgements will not stop the broker from sending more messages. You can simulate flow control by reducing MAX_UNACKNOWLEDGED_MESSSAGES on the endpoint to a point where the application can stop message flow by withholding acknowledgements. However that is a blunt hammer to solve this. MAX_UNACKNOWLEDGED_MESSAGES is intended to prevent one receiver from consuming too many resources. It is not intended for flow control.

Then I have a little bit confused and have a few questions here.

1) it there any recommended way to archive the behavior that only one message is pushed to the handler function?

2) when the event MessageConsumerEventName.MESSAGE emitted? is it the time a consumer received an unacknowledged message from the broker?

3) any performance downgrades by setting MAX_UNACKNOWLEDGED_MESSAGES = 1?

Thanks :D


Ref articles:

https://solace.com/blog/configuring-pre-fetch-for-optimized-load-balancing/

https://solace.community/discussion/comment/3681

https://solace.community/discussion/1160

Tagged:

Answers

  • devtony
    devtony Member Posts: 2

    Additional Questions:

    someone suggested adjusting the sliding acknowledgement window, which in Java by call setReceiveADWindowSize(). what is the equivalently control in Node.js library?

    The most similar control is WindowSize (https://docs.solace.com/API-Developer-Online-Ref-Documentation/nodejs/solace.MessageConsumerProperties.html#windowSize), but looks not affected.


    The window size for Guaranteed Message delivery. This is the maximum number of messages that will be prefetched from the Solace Messaging Router and queued internally by the API while waiting for the application to accept delivery of the messages.


    The valid range is 1 <= windowSize <= 255.