The program includes mqttClient.onMessage(myFunc), everything works fine until the unit receives a sequence of messages and not enough time in between to complete handling each message. This is causing reentries to myFunc and subsequently bricks the unit.
Is there a way to prevent re-entries?
Alternatively, is it possible cancel onMessage as the program enters myFunc and call it again when exiting?
I'm not familiar with the details of mqttClient.onMessage() but I suspect it is possible to disable it as the first thing within your function and re-enable it as the last thing in the function.
HOWEVER, I suspect the real problem is that your code is spending too long in your function.
What is the point in posting a snippet with what may be the most important piece empty
}
parseAndExecute(payload);
}
void parseAndExecute(String str) {
//handling hardware, may take several seconds to complete
}
If you really do want to ignore new messages for several seconds while something else happens then you need to disable the receipt of incoming messages until you are ready. For all I know that may also require changes to the code that is sending the messages - for example maybe it should wait until it receives a request from the Arduino.
Yes, I want to ignore new messages while handling current one but couldn't find how to disable the previously set onMessage() . From what I understand this is the only way to prevent re-entries.
Due to the asynchronous nature of the system we prefer not to go into server side solution.
Posting 1,200 lines of code will not add to anyone's understanding of the problem.
However, you real problem is that you do not understand what you can, and can not do, in a message handler.
//handling hardware, may take several seconds to complete
You can ONLY take "several seconds" to handle each message IF you make CERTAIN that the broker will allow you "several seconds" to complete handling each message.
If you can't, you can't take "several seconds" to handle each message.
Motto suggestion: "The art of giving good answer lies in understanding the question."
Your example will prevent executing the code fenced by doSomething but WILL NOT prevent reentering onMessageReceived which is the issue I am trying to solve here.
If what I am looking for do not exists, meaning a way to cancel mqtt.onMessage(), it may be a good idea to implement it in the library.
Your example will prevent executing the code fenced by doSomething but WILL NOT prevent reentering onMessageReceived which is the issue I am trying to solve here.
You are trying to solve the wrong problem, then. Having the function called, and taking no time at all to return is NOT a problem.
Robin2:
Why not make the onMessage() function very short. It just checks for a variable that says whether it can use or ignore a message. Something like
I prefer the guard clause to reduce the amount of nested indentations, especially in slightly longer functions.
myOnMessageFunction() {
if ( !okToDealWithMessage ) //return immediately if you can't process the message.
return;
okToDealWithMessage = false;
myFunc();
okToDealWithMessage = true;
}
Looking in another direction...
If I write reentrant/recursive code - I use a local counter to determine the depth of recursion... and simply throw an exception or return if too deep..