A catch with persistent file stores

Yes, would be good for several reasons, not least as it would give the API a workout.

@kuema the bones of the redis design is here https://github.com/node-red/node-red-context-redis/pull/1

Yes, I fully agree with that. But the lack of proper signalling support in Windows is an issue not only with NodeJS, but extends to other environments (Java, Python, ...) as well.

I was about to suggest to add that to the docs, but I just looked and the last sentence already states:

Note that if Node-RED is unexpectedly killed, any data that has not yet been flushed will be lost.

Could be more prominent, though. :sweat_smile:

I know what you mean. Apart from my day job I don't get much programming work done at the moment, either. Currently I have some "real world" projects (meaning in "hardware", not software) that need to get done. :grin:

Don't take on too many projects, Julian. I made that mistake several times. The outcome was counterproductive most of the time. :slightly_smiling_face:

Don't forget there is always the option (which is suitable, or even superior for many use cases) of using MQTT with retained topics rather than persistent context. The same problem will arise if MQTT is shut down unexpectedly as it also saves its data at a configurable interval to the file system, but presumably this is a less likely occurrence than restarting node red.

1 Like

Hmm, will the existing MQTT config nodes let me connect to them from my own node? They should do shouldn't they?

The main issue for me would be that MQTT wouldn't work well for a cache without significant extra logic. I wouldn't want to just re-push a single serialised topic for example as that would very quickly exceed the default max payload length for most MQTT brokers. So I'd need logic to split cache entries into separate messages and then still more logic to ensure that I could remove the retained messages as I needed to.

Might be an interesting exercise I suppose. Add likes to this reply if you think it worth while. If I get maybe 5-10 likes, I'll have a go. :grinning:

@TotallyInformation I'm sorry, I must have missed a step - why are you creating your own cache nodes to duplicate the functionality of Context?

Haha, I'm not. I'm creating a cache node that sort of replicates what chart Dashboard nodes do, allow automatic replay of messages on request (e.g. on reload of a uibuilder page or when a new client loads a page). It just has more options being in a separate node. Also, it lets other people use it.

It just uses the context store as a shortcut rather than trying to implement it's own store.

At the moment, it just records a set number of input messages (configurable). Later you will be able to control by topic and client/user id as well.

At the moment, people can do this with a function node easily enough but this is (hopefully) more robust and a lot easier for anyone with limited programming skills.

I don't pretend to know that much about Redis, but from what I recall, it holds the data in a memory store, and flushes it to disk at set intervals. Isn't that the same as what happens now with contextStorage?
What would Redis do different with the memory store if the system crashed, or (like node.js) failed to recognise the kill signal? I assume the data would be lost, exactly the same as it would with contextStorage.
If Redis was configured to flush data every second, isn't that the same as contextStorage doing the same?

Sorry if I've missed the point, but unless users are dealing with vast amounts of data that needs caching, and then writing in an orderly manner, I don't see the benefit of using Redis.

(Whilst typing, I see that this has already been mentioned)

OK, you are right - indeed all managed data engines will do the same thing for efficiency.

The big difference is that a user/admin can write a flow in Node-RED that will crash it. Similarly, not all nodes are as robust as they might be since so many of us are part-time programmers or have limited time/experience for testing.

A managed data engine is MUCH less likely to suffer from an issue like that. In addition, it will be a more monolithic type of application meaning that it can probably handle exceptions better anyway.

That doesn't help at all if the hardware or the OS crashes. But that is generally a much less likely occurrence.

For a single device install, you cannot escape the fact data has to be written to disk at some point.

Using an external service like redis means the flush to disk happens on a separate thread, so node-red doesn't appear to pause whilst it is happening. It is also what redis is designed for - so will be highly optimised.

From a scaling perspective, it also means you can have multiple node-red instances sharing the same context safely.

1 Like

If I understand correctly, the main problem (at least in the initial post) is not system crashes, or even node-red crashes, but that apparently on Windows a node-red restart may not shut down node red cleanly so it does not flush its context data to disc. Whilst using a db, MQTT or other separate service for the context store does not fix the issue if there is a crash it should sort it for node-red restarts. Normally one does not routinely restart db or MQTT servers so the problem should not arise, or at least be much less severe.

Should the conclusions drawn so far from this topic be added to the Graceful Shutdown design note?

What conclusions in particular? This topic has covered a lot of ground - not all of it pertinent.

The graceful shutdown design note is related to how a flow can be stopped cleanly - without dropping messages that are already 'inflight' within the flow. That is all predicated on the runtime being allowed to shutdown cleanly.

The context file store already does flush to disk when the runtime is being shutdown cleanly.

There is a separate issue over whether the runtime is being allowed to shutdown cleanly or not, depending on the many ways people chose to run it - nodemon, systemd, pm2... etc etc.

So, to summarize, it comes down to the issue of a graceful process shutdown when using Windows.

This is not an issue with Node-RED or NodeJS, but depends on how you start/shutdown Node-RED, e.g. the kind of process manager you use.

What we have seen so far:

  • manually from console: use ctrl-c and the process receives a SIGINT
  • NSSM: use the "generate a Control-C" shutdown option to simulate the previous; process receives a SIGINT
  • PM2: listen to the process.on('message') shutdown message (see docs for details)
  • nodemon: as far as I can see, sending signals does not work and it doesn't provide a workaround like PM2

For our Windows systems, we usually use NSSM for all NodeJS processes, as it provided the most reliable shutdown option so far.

FYI - I discovered this and reported it back in November (see Node-RED crashing at startup due to bad flow context (reproducible)) and opened an Issue about it (see https://github.com/node-red/node-red/issues/2369 )

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.