Use of msg, send, done in node that can also be triggered by button & more than one input msg to one logical process, when to call done?

Hello,
little question here:

For my sox record node i have the option that the user can choose whether to start recording on an input message or have no input but a button like the inject node instead to start and stop. So i just started implementing the 1.0 things like using send and done to tell the runtime when the node is done recording. So my question is do i somehow have access to the done function when the node was started with the button? As now the record function gets called from the request from the client and not from the on input function. When the record function gets called from the on input i pass the the msg, send, done to the record function. Right now i check if they were passed so the complete node will not be triggered when it was started with the button as i didn’t pass them than. Is there some way to access the done function and pass it when triggered with the button through a client request?

Johannes

Edit a little additional question.
As i said above when in msg control mode it makes use of the done function. As the node receives a start and stop message to control recording should i although call done for the processing of the stop message? as logically both input messages belong to the same process of the node i should only call done once right? As otherwise the complete node will trigger twice for one process. And if i call done only once should i use the done from the start or the stop message as this will change which msg the complete node puts out.

Yikes, that sounds complicated.

I would really love to try and help you, but I fear my lack of knowledge would not do you any help and probably waste more of your time that is beneficial.

But, if I am reading your question correctly:

The input is a user sent message to start (stop) the recording.

You are asking if the button (which I am not quite getting, but indulge me) is pressed/used to start the recording: you want to access the done function.

I think it is a layer thing here where you will have to have two parts working async'.
One recording and the other watching for incoming messages.

Then if/when a message is received it sends a signal (I won't say message: that is just making it more confusing than it needs to be) to the other part telling it to start/stop.

Am I understanding you correctly?

My understanding is that done() tells the user when it has finished the action initiated by a message, therefore done is not relevant if there is no message and if there are separate messages for start and stop then done should be sent when the start action is complete and another one when the stop action is complete.

have a look at the inject node, here https://github.com/node-red/node-red/blob/master/packages/node_modules/%40node-red/nodes/core/common/20-inject.js#L117

1 Like

yes the problem i have with this is that as the stop triggers the done of the start if it also has its own done the complete node will send two messages pretty much immediately after each other which logically just doesn’t make sense to me :no_mouth: and also do i call done for messages i ignore because i’m already recording? This would make a lot of stuff come out of the complete node that make it kind of not really useful for the purpose it was made for to see if the node was done?
But yes you are right if i call done at all i should probably do it for all messages.

Ah nice :+1: i looked at the code of the inject node before and missed that. So node.receive triggers the on input?
Edit
Thank you sir. Just tested and it works like a charm. Very nice as you can pass a msg object with the node.receive.

Thanks for your input :wink:

yes @cinhcet answered that function.

if you want to have more context you can look at the nodes code in question on github here:

although the version on github doesn’t have any of the 1.0 stuff in it yet and is fully 0.2 compliant.

I'll maybe stay away as I really think I am way out of my depth.

Sorry, I did not make myself clear. I meant that for the Start action, the action is complete when the action has Started. So arguably the done() for the Start message should be sent as soon as it has started. I think the thing to bear in mind is that this is provided for the user, so the key thing is, what would be useful to the user? In the case of a node with start and stop action messages then if the user sends a Start message possibly what he would want to know is when it has started. Similarly, if he sends a Stop message he might want to know when it has stopped.

Going back to the button, I still don't think that done() is appropriate since the action has not been started by a message. I don't think that the Inject node signals done.

No it doesn’t but it only has the the button and no input. My node can have either.

Yes i might agree that when the message is processed is the moment that the record process was spawned. So thats when the done for the start msg should be emitted but i can also see the other side which says that it only really done once the record process is finished as its attached to that start message.
I might go for the way you describe as this is how i already implemented it in the play node anyway and so it would make sense forma consistency point of view across the sox-utils nodes.

The other consideration is for the runtime. One of the reasons for adding all this done stuff is to eventually allow for controlled shutdown fo flows - so they can stop accepting new work but continue to process existing pipeline until they are all finished / done. So another way to think about it is has the node done what it was asked to do and is now waiting for the next task. So in your case I would argue yes - once it has started to record it has finished that request.

If on the other hand your node had a mode that one command recorded for say 10 seconds, then output that chunk... then done would be after it has finished recording and passed the message on... as the task is different,

So yes it is fairly simple for many nodes - but needs thinking about for quite a few also... like split / join etc... aka any node that goes 1 -> n or n -> 1. And no we haven't worked them all out - so any help appreciated.

1 Like

It has all those modes :upside_down_face:

Id value your opinion on the node.receive() issue. If i use it from the endpoint of the button to trigger the node the done messages also get triggered when my node doesn’t have an input and got started by a button press on the node. Should i rather call the record function directly from the endpoint rather than use node.receive() to prevent triggering done messages?

Thanks for all your feedback on the topic :raised_hands: The behavior is now implemented accordingly in the repo