'Persistent Context' variable names and 'Projects'...something to remember

There is some thing you should keep in mind when using projects and your flow is using 'Persistent Context' - the name of your variable.

Say you have project called 'greenhouse' and you create a global persistent context variable (stored in the local file system) called 'pump_status'. You run this flow and it store 'on' into the global. You shutdown Node-RED and start it up again and the global will contain 'on' just the way you want it to.

Then you create another project called 'sump_pump' to monitor and display the status of the pump pumping water out of your boat. In this flow you use a global persistent context variable and call it 'pump_status'. (you are probably starting to see the potential problem about now). Let's say this flow looks at the global 'pump_status' and displays it on a dashboard.

As soon as this flow starts, you get the 'pump_status', and it will be 'on' (that is what it is in storage). But maybe the pump is actually broken and the bilge is filling up and the boat is starting to flood...

So there you are, you just looked at the dashboard, see the pump shows 'ON' smile and swivel your chair to look out the window at your dock only to see your boat slowly sink under the water.

Don't let this happen to you!

Persistent variables exist in storage and any flow using them should either make sure the variable names are unique per flow or come up with a way to validate the data in the context variable is correct for this flow.

This will not be the case if you are running multiple instances of Node-RED AND each instance uses a separate user directory because the context data is stored in the user directory (when using the local file system) - unless the example above comes into play.

Another example of the dangers of using flow and global context. A much better solution to the particular problem you describe here would be to keep the pump status in a retained topic in MQTT. Then the problem would not appear in the first place as the greenhouse and boat topics would not be the same.

I don't use projects except for testing uibuilder. And I use a setup that lets me have multiple, independent installations of Node-RED.

So no problems for me :wink:

But useful info. Thanks.

1 Like

Lets say both flows published to a retained topic called 'pumpState'. Now explain why the MQTT solution would have been any different to the context solution.

Just as if the context names had been different.

Because one would not do that in the first place. The topics would identify either the sensor or the location, so maybe something like greenhouse/pumpstate and boat/pumpstate. If the two locations (boat and greenhouse) used different mqtt servers as might be the case in this particular example then it would not matter if the topics were the same.

@Colin - two things
(1) you are assuming everyone names their topics in a particular manner
(2) a lot of people (including myself) install MQTT on the same machine that they install Node-RED on.

What you are saying are good programming practices! The reason for this topic was to point out a edge case that most people will never hit, but if you did, you might be very confused as to the cause. After all you would need to (a) be using persistent context (b) be using projects (or if not using project, starting node-red and naming different flows) and (c) naming the variable the same name.

No, just assuming that everyone thinks about the data in their MQTT schema and names the topics such that everything there is organised in some logical manner. I do accept that this may be a gross assumption on my part.

Certainly, I was not in any way attempting to suggest otherwise. Just pointing out that one will certainly not hit it if one does not use global context for this purpose.

I may be reading too much into what is essentially an edge case, but I think there is a larger question of what we should expect or have options to request when changing from one project to another.

Currently, if a flow has un-deployed changes, the editor asks whether they should be deployed before closing the project. This is clearly necessary. In a previous thread, @knolleary suggested having an option to automatically commit changes to the project repo on each deploy or, as I suggested, when switching projects. In the same spirit, perhaps there should be an option to either retain or clear context variables when exiting a project. This could avoid the situation @zenofmud describes. It would also prevent a situation that may actually occur more often. If a project under development stores persistent context variables, they will effectively be initialized each time the project is re-opened. This may be what the developer wants, or it may have peculiar side effects that complicate debugging.

I am well aware that this final suggestion runs afoul of the current architecture for local filesystem context storage, but I think it would be ideal for each project to have its own context directory tree, with the ability to control retention independently. Implementation might not be hard, along the lines of how flow.json files are managed with and without projects enabled, but it might also not be worth the trouble.

@dceejay - when you set up projects, a new folder is added to .node-red called 'projects` and in it is a folder for each project you have with the flow for the project. Like this:

.node-red
-->projects
---->greenhouse
------>flow.json
------>flow_cred.json
------>README.md
------>package.json
---->sump_pump
------>flow.json
------>flow_cred.json
------>README.md
------>package.json

Why not have projects create a folder 'context` and use it from there?

.node-red
-->projects
---->greenhouse
------>context
------>flow.json
------>flow_cred.json
------>README.md
------>package.json
---->sump_pump
------>context
------>flow.json
------>flow_cred.json
------>README.md
------>package.json

Each project would include the context for just that project....

1 Like