Hi, I've been using an older version of Node-RED (1.2.9) for a while and it has been working great. I have flows that are handling multiple thousands of messages per second coming from a message broker.
I recently decided to update my version of Node-RED to a newer version (2.2.4) in order to install newer palettes that require Node-RED v2 or greater. Once I did this I noticed that my Node-RED instance wasn't able to handle the same amount of messages per second from the message broker that the older version was able to.
The flows would appear to be running as normal, but making changes such as enabling/disabling the debug node or making an edit and deploying would not take effect immediately, and it would appear that the flow still runs with the old configuration.
I can see the memory of the system slowly increasing over time, which leads my to believe that Node-RED is storing the input messages in memory and they are getting buffered quicker than the messages can be processed.
I decided to make a test flow to try to reproduce this behaviour in a separate environment to eliminate the message broker in the equation. I used Docker to run multiple different versions starting from 1.2.9. I determined that the flow works as I expect in v1.2.9 to v1.3.5, but something changed in the v.2.0.0 release that causes this behaviour.
Is this just an environment issue? I've tested on a couple different devices with different resources and the issue is reproducible on both devices. Is there a setting I could change that would fix this?
Here is the test flow that I've made
[{"id":"21f1836d8aed02aa","type":"inject","z":"f6f2187d.f17ca8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"0.001","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":130,"y":220,"wires":[["1fc8f3ec1b0af4ba"]]},{"id":"8d2b2bfd70b7107e","type":"debug","z":"f6f2187d.f17ca8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":510,"y":220,"wires":[]},{"id":"3ede02d65f3f6a01","type":"inject","z":"f6f2187d.f17ca8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"0.001","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":130,"y":280,"wires":[["1b5ea672305cd65e"]]},{"id":"5a96c53bae933a8b","type":"inject","z":"f6f2187d.f17ca8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"0.001","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":340,"wires":[["0c04a913fe01dd88"]]},{"id":"6c84a07a16070fb5","type":"inject","z":"f6f2187d.f17ca8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"0.001","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":400,"wires":[["38389c8db37b777f"]]},{"id":"dd6c0c01e39ae2a9","type":"inject","z":"f6f2187d.f17ca8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"0.001","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":460,"wires":[["387a397b2674643a"]]},{"id":"1fc8f3ec1b0af4ba","type":"function","z":"f6f2187d.f17ca8","name":"","func":"let ctx = context.get(\"ctx\") || 0;\n\nctx = (ctx + 1) % 10000;\nnode.status({fill:\"green\",shape:\"dot\",text:ctx});\n\ncontext.set(\"ctx\", ctx);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\ncontext.set(\"ctx\", 0);\nnode.status({fill:\"green\",shape:\"dot\",text:0});","finalize":"","x":320,"y":220,"wires":[["8d2b2bfd70b7107e"]]},{"id":"1b5ea672305cd65e","type":"function","z":"f6f2187d.f17ca8","name":"","func":"let ctx = context.get(\"ctx\") || 0;\n\nctx = (ctx + 1) % 10000;\nnode.status({fill:\"green\",shape:\"dot\",text:ctx});\n\ncontext.set(\"ctx\", ctx);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\ncontext.set(\"ctx\", 0);\nnode.status({fill:\"green\",shape:\"dot\",text:0});","finalize":"","x":320,"y":280,"wires":[["3c04f5df57f62903"]]},{"id":"0c04a913fe01dd88","type":"function","z":"f6f2187d.f17ca8","name":"","func":"let ctx = context.get(\"ctx\") || 0;\n\nctx = (ctx + 1) % 10000;\nnode.status({fill:\"green\",shape:\"dot\",text:ctx});\n\ncontext.set(\"ctx\", ctx);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\ncontext.set(\"ctx\", 0);\nnode.status({fill:\"green\",shape:\"dot\",text:0});","finalize":"","x":320,"y":340,"wires":[["23e3b5c2ac967f22"]]},{"id":"38389c8db37b777f","type":"function","z":"f6f2187d.f17ca8","name":"","func":"let ctx = context.get(\"ctx\") || 0;\n\nctx = (ctx + 1) % 10000;\nnode.status({fill:\"green\",shape:\"dot\",text:ctx});\n\ncontext.set(\"ctx\", ctx);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\ncontext.set(\"ctx\", 0);\nnode.status({fill:\"green\",shape:\"dot\",text:0});","finalize":"","x":320,"y":400,"wires":[["55b9465d93c9451c"]]},{"id":"387a397b2674643a","type":"function","z":"f6f2187d.f17ca8","name":"","func":"let ctx = context.get(\"ctx\") || 0;\n\nctx = (ctx + 1) % 10000;\nnode.status({fill:\"green\",shape:\"dot\",text:ctx});\n\ncontext.set(\"ctx\", ctx);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\ncontext.set(\"ctx\", 0);\nnode.status({fill:\"green\",shape:\"dot\",text:0});","finalize":"","x":320,"y":460,"wires":[["e8990acfc90d5a7f"]]},{"id":"3c04f5df57f62903","type":"debug","z":"f6f2187d.f17ca8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":510,"y":280,"wires":[]},{"id":"23e3b5c2ac967f22","type":"debug","z":"f6f2187d.f17ca8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":510,"y":340,"wires":[]},{"id":"55b9465d93c9451c","type":"debug","z":"f6f2187d.f17ca8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":510,"y":400,"wires":[]},{"id":"e8990acfc90d5a7f","type":"debug","z":"f6f2187d.f17ca8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":510,"y":460,"wires":[]}]
It has a function node that keeps a number in context memory and increases it every time it receives a message. I display this number as the node status of the function so it is easier to observe when the function is still receiving messages.
To reproduce the behaviour, I did the following:
- Ran docker image with: docker run -d -p 1880:1880 nodered/node-red:<version> (any version 2.0.0 or above should have the issue)
- imported json into flow and deployed the flow
- made a change to the flow, such as remove a wire from one of the inject nodes and deploy
- expected result: the function nodes reset their context and start counting up from 0 again (this happens in v1.2.9)
- actual result: the function nodes continue to count up from their current context values. Even the function that is disconnected from the inject node continues to count
I tried playing around with the inject node intervals and adding/removing copies of the flow. I've found that in v2.0.0 and above I start to see the behaviour around 1000 messages per second, where the older versions seem to not have any issues.
Any help to point me in the right direction on what's happening here would be greatly appreciated! This is my first post, if there's anything I've missed or any additional information needed please let me know.
Thanks,
Justin