Hi There,
I was wondering what is the best why to temporarily deactivate functionality within a flow?
Basically the scenario is a flow with a "production" representation and a "development" representation, each representation uses the same core functionality but production uses less of that functionality and has less debugging code. To have the production representation, I deactivate certain nodes thereby ensuring that specific parts of the flow are skipped, for example:
Here I skip the estimation of time and instead go direct to plotting some data. I sometimes use the estimation in development, so there is a reason why it's there.
Of course there are a number of ways to deal with this scenario:
-
create two distinct copies of the flow and maintain the two. The repetition of code here makes this solution if viable for me.
-
add switch nodes that refer to a global environment variable, something like if global.env.state == production ...
. I'd prefer the switch variation but the problem is that it's a switch node and it's not simple to see what it does or that it refers to a global value. (for me: this kind of "representation switching" is a "compile" time feature and the switch node doesn't make this clear). Also having to set global environments isn't that obvious (they don't tend to be visible in node-red) and setting them isn't that simple.
-
disabling nodes that should be skipped (as in the diagram). The disadvantage of the enable/disable nodes is that it's just one node of a flow (see above) and it's unclear that the rest of the flow (i.e. downstream) is also disabled. Also it is not clear why the node is disabled in the first case.
-
... better options?
Edit: To make it more clear what happens in that flow, here a "refactored" version:
now it's a bit clearer what happens when the node is disabled.
Maybe adding a msg property to your flows that distinguishes the development or production run. Then the switch nodes in option 2 could act on this property, which may be clearer to see why the switch is there, and no context to set or maintain, just change the msg property at start of flow in a change node labeled clearly. Or the change node could set the context value.
Could you use a gate/s with the status shown and activated by a global variable to alter the path/s through the flows?
that's what I am kinda of thinking - something that visually makes it clear which flow is taken.
Potentially it has the same issues as disable/enable: you only see the gate and have to look on to see the downstream nodes that are also "bypassed", i.e. disabled.
BTW this would also be useful for A/B testing whereby two different features are compared by activating one feature for X % of end customers and the other feature for (100 - X) % of end customers. Then conversion (or whatever is the KPI) is compared across the features.
1 Like
You could have two distinct copies in the same flow, as two groups "Production" and "Development".
You can disable an entire group with "Disable selected nodes", though there is no default keyboard shortcut for it and it's not in the right click options.
What I do in my case, is to use GIT and two node-red instances.
I have a Development and Production instances, and use GIT to transfer / update the flows between the instances, normally always from Development to Production.
Also have defined in settings.js
a variable that indicates if it is the production or development instance, and based on this variable have switch
and checks in some function
nodes to allow or disable some flow / ui functionalities.
Also use this as simple / complicated way to limit the data that some users / instances can see on the UI.
Yep that's the way it should be and perhaps my use-case is somewhat unusual. In my case this is a hobby project that only has one instance, so it's harder to split up flows.
true using groups for this would also be a good alternative.
One off-the-wall idea that I just had was to take concepts from graphic manipulation programs, e.g. gimp and photoshop. I've been doing a lot of graphics recently and one thing I use quite often are masks and layers. This gave me the idea (just now) that if there was a mask that I could overlay over my entire flow and use that mask to disable certain nodes (that's what masks do - they hide stuff). A layer concept would be showing or hiding certain nodes or section/groups of nodes - hiding would be the same as disabling.
Visually it could look a lot like the visual node selector, e.g. when using the catch node:
I would really enjoy a feature like that
And it would definitely make Node-RED become a cross-over development tool between visual manipulation and textual coding manipulation!
Not sure if this is particularly helpful for your application, but I use node-red-contrib-switch-break when I need to shut down certain aspects of my flows; such as ignoring a motion sensor. Works very well for that. I typically trigger mine with voice commands.
1 Like
I don't know that node, but I use node-red-contrib-simple-gate.
1 Like
Thanks for the tips and both are going in the direction I was thinking, especially the switch-break node. It seems to be able to control multiple breaks via one director, which is what I am looking for. Plus it has the centralised director which is lacking in the simple-gate node.
One improvement I could think of is to have a fork gate that directs traffic to one flow or another, i.e. a gate node with multiple outputs - a kind of fixed switch node ...
1 Like
You're right about this. I'm able to accomplish something like that with and/or gates and the occasional function node, but your suggestion would really improve and simplify things.
Could perhaps my node-red-contrib-msg-router be of any help?
I use the node-red-contrib-simple-gate for this and open/close the gate to different sections. The included examples are good to get you using it.
Have you thought about using Node-Red subflows for the common part of the functionality. When using subflows you don't have to duplicate code for example if you make different flow for development and production.
https://nodered.org/docs/user-guide/editor/workspace/subflows
I decided on switch-break because that has a centralised switch mechanism, so I have two directors (development and production) and a number of actors that are controlled by the directors. That provides the centralisation I was looking for.
I avoid subflows preferring custom nodes for encapsulating functionality. Subflows are good for specific use cases but I generally try to work around them. I recently discovered flow-manager that makes working subflows more transparent - I might have a look at that.
2 Likes