React on NodeRed exit event

Hey folks,

im seaching for a way to react on an application close event of node-red inside the nodes.
Im using it as an embedded app and I figured out, that on a kill signal nodeRed will stop gracefully and running the onClose functions of the nodes.

My Problem:
I can not distinguish in the onClose method between a deploy or an application close. Apparently i have to clean up stuff if the app is closing which should not be cleaned during the normal onClose event which happens on the deploy.

Is there a way to achieve this? Is there maybe an Event in RED.Events?

Thanks for any hints!

What additional stuff do you have to clean up when the app is closed?

it is an event stream to an external application which should stay open until it is closed by the last node or by an exit of the application.
One option would be to deregister all my listeners and close the stream and reopen it again and register everything all over but since the event stream is used to gain events from devices i would like to bother the devices as less as possible.

But apart from that i really would like to know if there is any possibility to detect what kind of event was triggering the closing or beeing able to attach my own application closing events

If you only deploy modified nodes or flows then the unaffected nodes should not get closed.

1 Like

Thanks for the hint! But i am not in control of choosing the deploy mode.
I am only participating in the node which should work with several devices and only one event stream on multiple flows.

So i guess there is no such closing Event?

I presume that you add a listener each time a node is started. You could keep a track of how many are open, and in the node close event, close the listener for that node and close the stream if there are none left open.

To answer this point directly; no, there is no way for a node to know it is being stopped due to a deploy or because the runtime is stopping entirely.

The Event stream is a singleton.
So i can ensure that the stream is beeing connected only once.
The Stream is beeing used in multiple nodes. It enables the nodes to communicate with the device.

I already collecting every subscription of any node inside the singleton class. I register it with a key which contains the Z property of a node (so that i know on which flow it exist to enable or disable only the listeners on that specific flow.)
It is one node which can subscribe and unsubscibe to events of the devices and they register callbacks for the DeviceEvents.

If i am doing this what you suggest i would end up deregistering all listeners in the onClose and at some point there is no listener left and than i would close the Stream.
This does work and is also my current implementation, but after a deploy the listeners have to be registered again. So i have to persist them somewhere. Also i am not allowed to use the storage system of nodered (flow context on disk).
We do not want to hold any states inside this flow.

This is why i came to the conclusion: not deregistering on deploy and only on manual trigger or application closing.

Anyway good hint with the caching of listeners!

Thanks knolleary for confirmation.

Have you considered the more usual configuration of having a config node holding the connection and the listener nodes being attached to that config node? Much like the MQTT nodes for example.

1 Like

Hey Colin,
yes and thats also a great idea! But i am not allowed to make breaking changes on our node apis in this release. But i planned it already for a future release.

I clarified again with our other developers and they already changed it to deploying on modified flows.
Thanks for bringing up this topic again :slight_smile:

I ended up with an singleton for the eventStream which holds also all listeners across all nodes and flows.
On a close only the listeners of the flow of the node will be removed. Afterwards the size of all listeners are checked and if it is 0 the eventstream will be closed.

Just finishing some unit and integration tests.
thanks to all of you!