-
Notifications
You must be signed in to change notification settings - Fork 5
Description
This seems to be related to the discussion in this closed issue.
The Problem
If you send a message to which the receiver doesn't reply immediately, you don't get notified if it later times out.
The problem is that:
- If the receiving callback doesn't immediately reply() to the message, its automatically acknowledged
- When the _processQueues() function is run, if a message has timed out and ack() has been called, it's deleted from the sent queue.
- Our onReply() function is never called, but neither are our onTimeout() or onFail() functions
- We're left wondering what happened to the data we were expecting
Fix
Change the check in _processQueues() to call the onTimeout function if there's an onReply function defined.
if (!msg._acked) {
changes to
if ((!msg._acked) || (_isFunc(msg._onReply))) {
Example Code
This setup works:
Sending side
mm.send(
"EXAMPLE",
{},
{
onFail = function( message, reason, retry ) { server.log("FAIL"); },
onTimeout = function( message, wait, fail ) { server.log("TIMEOUT"); fail(); },
onReply = function( message, response ) { server.log("REPLY: " + response); },
onAck = function(message) { server.log("ACK"); }
},
5, // Timeout of 5 seconds
null );
Receiving side
mm.on( "EXAMPLE", function( message, reply ) {
imp.wakeup( 1.0, function() { reply("OUR REPLY"); }.bindenv(this) );
});
Results:
ACK
REPLY: OUR REPLY
But, if we change the timeout and the asynchronous delay, we don't get any notification. If the receiver delays for 10 seconds imp.wakeup( 10.0, function() { reply("OUR REPLY"); }.bindenv(this) ); then what we see is:
ACK
/// That's it...
Pull Request
This change is a bit opinionated - so I haven't made a PR yet, but I'm happy to if you agree it's a good approach.