This is something I wrote up after playing with the context options. I've filed a PR with some of this added to the Node-RED documentation but thought I'd release it here also. I hope people find it useful.
Paul
A guide to understanding 'Persistent Context'
Prior to Node-RED v0.19.0, data could be stored in context as a global, flow or node. This was stored in memory and would be reset with a restart of Node-RED. As of v.0.19.0 you can now store node, flow and global context data in memory OR in a file which will persist over restarts. (the data will be stored in the userDir, which is normally $HOME/.node-red, in a folder 'context' with subfolders for each flow or node and one folder for all globals.)
In order to store the data, you must make a change to settings.js
- without the change, context stores will always be in memory and will not be persistent.
The contextStorage property in settings.js is used to configure how context data is stored:
contextStorage: {
storeName : { module: "storeModule" }
},
storeName
: The storeName used in get/sets
storeModule
: Node-RED provides two built-in store modules: memory
and localfilesystem
. It is also possible to create custom store plugins. You must specify localfilesystem (or your own custom module) to make the data persistent. For details on creating custom modules, see the api pages.
If you only have one option in contextStorage, it will always be used. If you have two options and one has the storeName default
(order doesn't matter) it will be used if the get/set storeName option is not used. If you try to get
or set
using a location storeName that does not exist, it will use the default and you will see a one time warning in the log.
Example: say these are your entries in setting.js:
contextStorage: {
storeInFile: { module: "localfilesystem"},
default : { module: "memory" }
},
And you use the following set's (this applies to any node that can access context directly like the change, inject, or change nodes):
flow.set("count", 123); // stored in memory, count = 123
flow.set("count", 234, "default"); // stored in memory, count now - 234
flow.set("partid", "b301", "storeInFile"); // stored in file, partid = "b301"
flow.set("color", "red", "InFile"); // invalid storeName
// - stored based on 'default' rules
// - a 'storeName' of `default` exists and is used
// - stored in memory, color = 'red'
Note: Having multiple entries in settings.js can lead to confusion. If you have:
contextStorage: {
default : { module: "memory" },
storeInFile: { module: "localfilesystem"},
memoryOnly : { module: "memory" }
},
and run the following code:
flow.set("count", 123); // the value is stored in memory
flow.set("count", 234, "default"); // the value is stored in memory
flow.set("count", 345, "memoryOnly"); // the value is stored in memory
the first line stores '123' in default:count.
the second line replaces '123' with '234' in default:count
the third line stores '345' in memoryOnly:count
If you forget to specify the location in a get
or set
, you might end up with the wrong value.
SUGGESTION: If you want have all your context data be persistant, setup your settings.js file with the following:
contextStorage: {
default : { module: "localfilesystem"}
},
Here are some more examples
Example 1: default to memory, require a name for storing in a file
contextStorage: {
default : { module: "memory" },
storeInFile: { module: "localfilesystem"}
},
flow.set("count", 123); // the value is stored in memory
flow.set("count", 234, "default"); // the value is stored in memory
flow.set("ID", 345, "storeInFile"); // the value is stored in a file
flow.set("date", 345, "somewhere"); // since there is no storeName "somewhere",
// and there is a storeName "default",
// the value is stored in memory
Example 2: default to persistant require a name for storing in memory
contextStorage: {
storeInFile: { module: "localfilesystem"}
memoryOnly : { module: "memory" },
},
flow.set("total", 123); // since no option is provided and there is no "default"
// option, the first option "storeInFile" is used so
// the value is persistant and stored in a file
flow.set("count", 234, "memoryOnly"); // the value is stored in memory
flow.set("ID", 345, "storeInFile"); // the value is stored in a file
flow.set("date", 345, "somewhere"); // since there is no storeName "somewhere" and
// there no storeName "default" the first
// storeName is used ('storeInFile') so the
// value is persistant and stored in a file