In this project GitHub - golfvert/WIS2-GlobalBroker-NodeRed: Basic reference of a Global Broker for WIS2 available as a ready to use container, I am making use of https://flows.nodered.org/node/node-red-contrib-redis .
This contrib node works great.
At the moment, I am using redis in a non-cluster mode. And as part of the setup, a redis instance must be on the same docker bridged network.
I'd like to change that and be able to use an existing redis service that could be in cluster to improve reliability.
However, the current node doesn't permit the configuration of the cluster mode dynamically (eg. through an ENV variable or using dynamic msg input). Typically, what is possible with the excellent MQTT nodes.
I wonder what are the options here.
asking the maintainer to add this feature ? I've done that, maybe that will happen...
If not, some ideas on Plan B:
forking the repo and add this feature myself. Is there some simple example how I could use to do that. Typically, another contrib node having this feature that I could "borrow"...
having two config nodes one with cluster and one without and be able to switch dynamically at startup ? Not sure if that is doable as the flows.json is part of the container and is not stored on a permanent volume.
Any node property can be set with an environment variable by setting its value to a string of the form ${ENV_VAR}. When the runtime loads the flows, it will substitute the value of that environment variable before passing it to the node.
This only works if it replaces the entire property - it cannot be used to substitute just part of the value. For example, it is not possible to use CLIENT-${HOST}.
As nodes provide their own edit dialog, not all properties will provide a text input that can be used to enter the env-var string. In that case, you may consider hand-editing the flow file to set the property.
The "option" (that is the name of the server) can be set using ENV. No problem.
The "cluster" being a tick box can (only?) be via the interface.
I know that in eg. the MQTT config node the TLS option is a tick box but can be defined with an ENV variable through the broker url config. I guess the js is more clever than the one from the redis node. Looking at the code of this redis node (node-red-contrib-redis/redis.js at master · chameleonbr/node-red-contrib-redis · GitHub)
I can't see it being able to parse any ENV variable to get the true/false option I am looking for.
The code of the node for the cluster part is:
try {
if (config.cluster) {
connections[id] = new Redis.Cluster(options);
} else {
connections[id] = new Redis(options);
}
config.cluster being the tick box above.
I have considered changing the flows.json out of the UI before publishing the docker container (the flow file is part of the container and can't be changed - by design).
However, ${ENV_VAR} are strings and the cluster option waits for true or false (and not "true" or "false"). This is where I am stuck.
From what I can see, if you were to set the "redis-config" node property "cluster": "${CUSTER}" in the flow file AND set the actual env var CLUSTER to anything it would pass as truthy. Leaving it unset would be falsy and therefore should work
Then even if REDIS_CLUSTER env var does not exist (it will/should be evaluated to "cluster": "") and it ticks the box
The only way for cluster to be off, is with "cluster": false
Ah, perhaps try setting the env var REDIS_CLUSTER to an empty string?
I think if the environment variable doesn't exist then the value ${REDIS_CLUSTER} is being used?
Quite easy to check with a temporary console log entry added directly into the source file.
try {
console.log("config.cluster = ", config.cluster) // add this
if (config.cluster) {
connections[id] = new Redis.Cluster(options);
} else {
connections[id] = new Redis(options);
}
To be fair, this may be a flaw (or rather a design choice) where it doesn't discern the subtle differences between missing and empty. Give it a go. See what happens. Let us know.
That is unfortunate. In an ideal world where we all wear hindsight glasses, an empty (but defined) env-var would evaluate to '' but that would be a breaking change now.
There is still hope.
try adding it to THE TOP your settings.js (before module.exports) as follows...
process.env.REDIS_CLUSTER=false
What does console.log("config.cluster = ", config.cluster) show you now?
console.log("config.cluster = ", config.cluster) gives the value sets in settings.js with false, 0, null.
Only '' gives ${REDIS_CLUSTER}.
I am running node-red in Docker. After each change, I restarted the container and reloaded the web page.
I also have a very basic test that works when the box is unticked. And with all those values, it fails. So, the tick box is not related to some caching issue.
well I guess you are going to have to either pre-load a modified version or fork it
The "good" fix to use env vars is to change the option to a typedInput (permitting a choice of "bool" and "env") and ensure you do a more specific test (like below)
The quick fix is to leave the UI alone and just be more specific on the test:
try {
console.log("config.cluster = ", config.cluster) // add this
if (config.cluster === "true" || config.cluster === true) {
connections[id] = new Redis.Cluster(options);
} else {
connections[id] = new Redis(options);
}
At the moment, the dependencies in package.json fetches the official contrib mode. I need to understand how to use my own...
Thanks again for your help.
Enjoy what is left of Sunday