Rate-limiter now supports queueing

I uploaded a new version of my little custom node rate-limiter.

With this version it supports not only sending messages above the rate limit to the 2nd output, but also allows to have them buffered and sent whenever the rate limit allows.

Next I plan trying to get the 2nd output to vanish if not needed, but that seems not to work so far. :slight_smile:

1 Like

I got some help on this from the Forum, but I can't seem to find the thread. If you look at the html file for node-red-contrib-multiple-queue you will find a solution.

Thank you @drmibell.
Turned out not to be that hard, if you spot the typo after a while of pulling your hair out.

This thread helped: How can my custom node have dynamic number of outputs?

Next up is adding an option to limit the size of the queue. Could be done either (A) by putting a hard end to queueing if limit is reached, or (B) by removing the oldest element in queue and adding the new msg.

If in mode (B), the node would support what was discussed here Can the Delay node rate limit, but pass first message immediately, and always pass on the latest message? if set to queueing, limit queue = 1, mode (B).

Right. That was the one I couldn't find.

From the thread you linked, you obviously know that node-red-contrib-queue-gate supports these features. They're not difficult to implement.

It's very interesting (at least to me) how this sort of discussion keeps cropping up. How should we distinguish between delay, queueing, and rate limiting? If we design nodes for one of these functions, how much overlap with the others do we need or want? Also, lurking in the background are questions of race conditions and asynchronous execution that could require semaphores or similar mechanisms. At some point, I get a headache and stop worrying about it.

2 Likes

Well, at first I thought about it, but then I remembered that node-red processes basically single-threaded and if I understand correctly, the node can process a message without having to fear (or protect itself) of being interrupted. So no need for semaphores; BTW, does this concept exist in JS?
Besides, when you require precise timing in the milliseconds, I think node-red is not the tool of choice.
Like you said, I do not worry that much about stuff like race conditions and very precise timing.

I just realized that you are the author of q-gate (right?). It is a very handy node and I think I used it in the other thread to model the situation described above:

However, q-gate does not include timers, and that is ok. It is very powerful at what it does. I also used it in my solutions to the requirements posted in the above thread.

A good question, but I think not that hard to answer, at least for me.

  • Delay is sort of a slow down, generally it does not need to be applied uniformly, but if you discriminate against rate limiting I think it is applied uniformly, hence not affecting the rate.

  • Rate Limiting means generally to limit the rate of messages. One way of doing that is by delaying messages that exceed the desired rate limit. But of course other modes are possible (e.g. dropping messages).
    The way this is done in the normal delay node is mostly fine and if the setting is 1 msg/TIME it matches my understanding of rate limiting.
    What I didn't like was how it dealt with n msg/TIME for n>1, because it translates to 1 msg/(TIME / n).
    e.g. For me 5msg/5s is not the same as 1msg/1s.

  • Queueing is putting messages somewhere to process them later.

When applying delays in general the question "How to deal with excess messages?" is relevant. Queueing is one way to deal with excessive messages, another way would be dropping the excess msg. Not sure if there is other ways of dealing with excess msg? For each mode (dropping/queueing) many modes of operation seem possible.

In any case, for me using node-red is no business and creating a custom node was/is more like a way to learn stuff and just having the challenge. That means I did not think extensively how we should structure nodes and which node does what and where is overlapping.

I did not mean that the words are hard to define, just that drawing boundaries when implementing the functions can be tricky. As you say, delay or rate-limiting nodes may need some queueing capability, but how much is enough? Should they have options to flush, reset, move to the head of the queue, etc.? The line between needed improvement and "mission creep" can be blurry. (BTW, my q-gate node was a response to the question of how to deal with messages that didn't make it through the simple-gate node when it was closed. The multiple-queue node evolved from q-gate, and so on...)

I actually use NR professionally, but writing nodes is incidental to that, and the ones I publish are just for fun.