Batch node group by time interval

Dear all,

Is that possible to collect a set of messages in less than 1 second?
Batch node supports this function only for more than (or equal to) 1 second. It is that possible to create a Python or Javascript node to achieve that?

Best
ZaoTX

Welcome to the forum @ZaoTX

So that we can understand exactly what you want, does the batch node do exactly what you want except for the interval size? Make sure you test it before answering that please.

If so can you explain why you want them grouped like that?

Hi Colin, yes the batch node does exactly what I want except for time interval.

The reason is I want to use Node Red to synchronise multiple interactions to the same object in other program. I want to collect the messages of interaction in a small time interval and synchronise on Node Red send it back, so that the synchronisation doesn't affect users'(multiple users) experience.

How small an interval do you want to go? Node-red uses nodejs which is mostly single threaded, which means there can be delays in response. It depends what hardware you are running on, of course, but there may occasionally be delays of a measurable fraction of a second as, for example, memory garbage collection is done.

Is that possible to do it for 0.5 second? 1 second works not so perfectly, 0.5 would be the best option. By the way the hardware should be a NUC with 8g RAM

It is certainly possible to build a flow that will work for low intervals. It is whether it will actually achieve what you want that I am not sure of. Install node-red-contrib-queue-gate and then Import this flow

[{"id":"e077630445be3951","type":"inject","z":"bdd7be38.d3b55","name":"0.5 second trigger","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"0.5","crontab":"","once":false,"onceDelay":0.1,"topic":"control","payload":"flush","payloadType":"str","x":190,"y":1140,"wires":[["21eb8f3faca0977c"]]},{"id":"9e58be87e19370f0","type":"debug","z":"bdd7be38.d3b55","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":550,"y":1040,"wires":[]},{"id":"21eb8f3faca0977c","type":"q-gate","z":"bdd7be38.d3b55","name":"","controlTopic":"control","defaultState":"queueing","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","queueCmd":"queue","defaultCmd":"default","triggerCmd":"trigger","flushCmd":"flush","resetCmd":"reset","peekCmd":"peek","dropCmd":"drop","statusCmd":"status","maxQueueLength":"100","keepNewest":false,"qToggle":false,"persist":false,"storeName":"memoryOnly","x":390,"y":1040,"wires":[["9e58be87e19370f0"]]},{"id":"ae04214f6520f6f6","type":"inject","z":"bdd7be38.d3b55","name":"Messages to be batched","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":1040,"wires":[["21eb8f3faca0977c"]]}]

You can adjust the release interval in the lower inject node. It can be set to fractions of a second. It is easier to see that it works if you set it to 5 seconds initally.

image

Thank you very much, I will download that in local server tomorrow. What you suggested looks totally good. Thank you again for your quick and useful rely!

Also possible with standard nodes. You can use a join and split node, join as array, with 0.5 second timeout.
e.g.

[{"id":"4491ccca.65474c","type":"inject","z":"bf9e1e33.030598","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":120,"wires":[["68e8baf8.1fdc14"]]},{"id":"68e8baf8.1fdc14","type":"join","z":"bf9e1e33.030598","name":"join as array","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"0.5","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":310,"y":200,"wires":[["69a0117e.1dc2c8"]]},{"id":"69a0117e.1dc2c8","type":"split","z":"bf9e1e33.030598","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":470,"y":200,"wires":[["336e4e45.8dadba"]]},{"id":"336e4e45.8dadba","type":"debug","z":"bf9e1e33.030598","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":650,"y":200,"wires":[]}]

I don't think that quite does what (as I understand it) @ZaoTX wants. I believe he/she wants them released on a regular tick. The Join node releases a defined time after the first message is received, which is not quite the same.

Then just feed in an inject sending msg.complete every 500ms

Thank you for your suggestion. There is indeed some differences, but thanks a lot for providing me with different possibility to achieve that. I didn't know that before you tell me this method

That works.

Or we could look at a simple Pull Request to the batch node to set the step to 0.5 with a minimum of 0.5 ?

Hi Colin, I connected a join right behind the q-gate. Then, an error occurred, it said "Message missing msg.parts property - cannot join in 'auto' mode". Is it because that the sender only sends 1 message in the 0.5 second interval and the join is not compatible to single message input? Can you tell me how to resolve this issue?

Ops, when I set mode of the join node to 'Manual' and set send the message after number of message parts to 1. Everything work again.

I don't understand now what you are trying to achieve. Why are you using a Join node?

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.