André Fachat André Fachat - 4 months ago 59
Node.js Question

Concurrent access to msg/payload on split flows in node-red?

I'm working on a node-red flow and came upon some (hopefully not real) concurrency problem.

I have a node outputting a msg.payload, that on one connection is written to a database. The database insert node is dead end, so another connection from the first outputting node goes to a function node that overwrites the msg.payload again, needed for the HTTP reply.

I'm wondering about the ordering of execution in this case, or rather the protection against the database accessing the modified msg.payload when it runs after the function node.

Obviously this seems to work - but I would like to know if this is just chance, or is the msg object cloned before each function, or on multiple outputs?


There is no concurrency issue as Node-RED is totally single threaded (as are all NodeJS apps) so only one leg of a branching flow can actually execute at any given time.

Flow execution branch order is in the order the nodes were added to the flow, so for assuming nodes were added in order A, B, C, D, E

A ----> B ---> D ---> E
    --> C

The message will be delivered from A to B to D to E then to C (assuming that none of B,D,E block for io)

Also messages are cloned when there are multiple nodes hooked up to a single output, you can easily test this with the following flow:

[{"id":"9fd37544.36664","type":"inject","z":"8b231c78.b8edc8","name":"","topic":"","payload":"foo","payloadType":"str","repeat":"","crontab":"","once":false,"x":269.5,"y":284.25,"wires":[["48eda9a0.b455e8","e1f3c665.9af04"]]},{"id":"48eda9a0.b455e8","type":"function","z":"8b231c78.b8edc8","name":"","func":"msg.payload = \"bar\";\nreturn msg;","outputs":1,"noerr":0,"x":454.5,"y":283.75,"wires":[["5f27ffc7.a54ce"]]},{"id":"5f27ffc7.a54ce","type":"debug","z":"8b231c78.b8edc8","name":"","active":true,"console":"false","complete":"false","x":635.5,"y":284.5,"wires":[]},{"id":"e1f3c665.9af04","type":"debug","z":"8b231c78.b8edc8","name":"","active":true,"console":"false","complete":"false","x":475.5,"y":362.5,"wires":[]}]

This has a single input that flows to 2 debug outputs, the first branch includes a function node which modifies the payload before it is output.