🎉 Node-RED 1.0.0-beta.3 released

Exactly my point.

A while ago I actually had the case that a flow broke (or misbehaved) because the message has been cloned. So more (unnecessary) cloning should be avoided, or at least have the means to avoid it.

I think it is necessary to be clear and consistent about when a message gets cloned by the runtime, and when a user (or node author) is required to clone a message before sending it.

E.g. I know that the runtime clones the message for everything but the first output wire, because I read it somewhere on the Google group back then. Thus I know to keep that in mind. But that should be documented somewhere.

2 Likes

#offtopic

This is the main reason I wish for a true inline debug node. To minimise message cloning.
#end_offtopic

1 Like

#offtopic

Me too. A debug node was exactly the reason for that "little", hard-to-find bug. :grin:
I attached the debug node first, the processing node later. Debug got the original, the other node the copy... bang. :zap::laughing:

#end_offtopic

Yes, we have seen various areas of node.js and Node-RED itself subject to performance improvements. JSONata for example has had a number of improvements.

I can point to Windows 10 as well, that has had major performance improvements in various areas.

I think the point here is that the change suggested to the send function actually changes it to work more like users (especially non-expert ones) would anticipate.

I would agree certainly - but as said, I'm not convinced that is the outcome. But of course, you see more of the issues coming in that I ever will so ultimately, it will be quite correctly your call.

I think along with the coming flow changes in v1.0 this is going to be very interesting.

A change in this area should be taken under great consideration, as flows might break both ways. On the one side flows that were mistakenly sending the same message object multiple times. And the other where a copied message would actually break the flow.

I encountered both issues, some by mistake and some by missing prior knowledge about the internal handling. So I believe consistency and documentation is key here.

From performance perspective; is there any difference to clone the existing msg or to create a new one like msg1? What is worst?

It depends on the message.

If your messages are relatively small, I doubt you'd be able to notice any difference unless you're doing 100/1000+s of messages a second.

If your messages contain a large amount of data, the cloning will be more noticeable as the data has to be copied.

Hi @kuema, indeed cloning all messages would become a killer for all my audio and video related messages. My poor raspberry will never survive such a change :wink:

@BartButenaers right, but if you follow the rest of the conversation, this is a change we need to make.

The question is how we allow a Function to send a single message without it being automatically cloned.

There are essentially three options:

  1. node.send([msg]) - sending it as an array of one element (which works today) could be used to indicate it should not be cloned.
  2. node.send(msg, false) - a second optional argument that will disable any cloneing the Function node does.
  3. node.sendWithoutClone(msg) (or some better named function)

Option 1 is hacky and non obvious. It may also still catch some people out as that is semantically valid code today.
Option 3 goes down a route of having to name a new function and no-one likes naming things
Option 2 is probably the cleanest solution.

What you must all realise is that whichever option we take, this will only disable the additional clone we will be introducing when a single message is passed to node.send(). If the node is wired to more than one other node, cloning will still take place. If you pass an array of more than one message, cloning will still take place.

And this will only apply in the Function node. A custom node will be responsible for its own cloning or not, just as it is today.

4 Likes

To summarise - the proposal is
Inside a function node

  • node.send(msg) - will clone
  • node.send(msg,false) - won't clone
  • return msg; - won't clone

Inside a custom node

  • node.send(msg) - won't clone (as per today - developer is responsible).

Also as per today - if you wire multiple wires to any output of any node then the second (and subsequent) wire(s) will get a cloned copy regardless.

5 Likes

"Option 2 is probably the cleanest solution"

Could you not add that new param in the FIRST position instead? Like I wrote above, node.send(false, msg) since this will allow you to use a text editor and make an easy search and replace? I would for instance do "search" node.send( "replace with" node.send(false,

Otherwise, maybe possible, but how would you do a search & replace in an easy way if you would like to use a text editor? Why force users to edit directly each and every function node???

No. Optional arguments do not go at the front. The design of an api is not determined by the convenience of using search and replace.

My text editor (atom) will let me search use regex, which would have no issue make the sort of update you are talking about.

3 Likes

Why force users to edit directly each and every function node???

It sounds more like you are forcing yourself.

Correct me if i'm wrong, but without cloning you will run into problems while modifying the same object using node.send within the same function node.

And you do this in every function node that you even need the function to be implemented in a non-standard way so that you can "easily" replace it with a text editor ?
Flabbergasted :robot:

Another reason against this is that it will change the order of the parameters and thus break every single function that uses it at the moment. While I understand it’s a breaking change either way, there’s going to be old documentation and tutorials hanging around and future users learning/attempting to use the old syntax. Even when changing the syntax, new parameters (especially when optional) are better added to the end, especially in a language like JavaScript where you can’t specify keyword arguments thus all arguments are positional.

2 Likes

I think you don't wan't a simple search and replace, as you will need to check each location individually to see if there are any problems with the messages.

@knolleary, I can't agree more! But seems I haven't expressed myself correctly: just wanted to emphasize that not all flows deal with teeny weeny messages, so always cloning could become a killer ... This major release is a great opportunity to introduce this change. And option 2 is indeed a VERY neat and decent solution! And anyway my audio/video stuff would keep running with or without cloning, with only an (immediately) visible drop in performance. If the release notes mention that - in case of performance issues - these send statements might be the root cause, then it is only a matter of adding booleans manually...

So :+1::+1::+1::+1::+1:

3 Likes

You are assuming something not relevant to my setup. I am just looking for a convenient way updating large flows. I have already sorted it out once, now just awaiting to make a second round, all depending on decisions made here, I think I noticed earlier up in the thread, "A change in this area should be taken under great consideration". Computers are supposed to work for you, not against, right?

Anyway, I don't care now, I know my flows, I will sort them out, What you do, well, good luck

Ok,Ok,Ok,Ok,,,I give in

Unless you are node.sending large messages, or are sending messages at a very high rate, then the proposed change will mean you should not need to do anything at all with existing flows. I believe this will not be a breaking change except in a very very small number of cases.

We have seen some cases of this in the forum and this is likely to grow as more people continue to discover Node-RED.

I'd certainly be happy with either 2 or 3.

I think that your other restrictions, while a little complex, are not unreasonable and would be expected once you know how JS works - but of course, will need some reasonably clear documentation.

1 Like