# Can the Delay node rate limit, but pass first message immediately, and always pass on the latest message?

**URL:** https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170
**Category:** General
**Created:** [31 August 2022 08:34 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170 "2022-08-31T08:34:55Z")
**Posts on this page:** 20
**Page:** 3

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [1 September 2022 10:18 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/43 "2022-09-01T10:18:03Z")

</div>

> [@Trying\_to\_learn](#):
>
> The one with the `qgate` is probably the one I would put my money on as being best matching.

As I pointed out there are race conditions with that one that mess it up. In particular if two inputs arrive at virtually the same time then they will both get through before the gate closes. Attempting to modify the Trigger one to add the feature will also, I am confident, have race problems.  
I suspect the only way to fully satisfy it is to write a function or add the feature to the Delay node.

---

<div class="post-metadata">

### Author: ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)
#### Post date: [1 September 2022 10:48 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/44 "2022-09-01T10:48:44Z")

</div>

You are absolutely right @Colin, my suggestion has potential race conditions and attempting to prevent them just moves the race somewhere else.

Isn't @dceejay's solution exactly right though?  
Just standard nodes and no fancy control messages (as I recall). Clearly a man with a deep understanding of the language 😉

I did download @Trying_to_learn's suggestion but it included a node that I don't have installed so I did not test it.

---

<div class="post-metadata">

### Author: ![UnborN](https://avatars.discourse-cdn.com/v4/letter/u/4491bb/32.png) [@UnborN](https://discourse.nodered.org/u/UnborN)
#### Post date: [1 September 2022 10:58 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/45 "2022-09-01T10:58:36Z")

</div>

Can this work ? ..

```auto
[{"id":"ec06a50fb93ee157","type":"inject","z":"54efb553244c241f","name":"MSG A","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"MSG A","payloadType":"str","x":150,"y":2000,"wires":[["0769b75f987235ba"]]},{"id":"863f7eb764566564","type":"inject","z":"54efb553244c241f","name":"MSG B","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"MSG B","payloadType":"str","x":150,"y":2060,"wires":[["0769b75f987235ba"]]},{"id":"4943efe9118b71f4","type":"inject","z":"54efb553244c241f","name":"MSG C","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"MSG C","payloadType":"str","x":150,"y":2120,"wires":[["0769b75f987235ba"]]},{"id":"60849786e5e2203c","type":"trigger","z":"54efb553244c241f","name":"","op1":"","op2":"flush","op1type":"pay","op2type":"str","duration":"5","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":2,"x":400,"y":2060,"wires":[["e9db8f4747aaf9e2"],["17740c7f7eaee224"]]},{"id":"d8eba91018d2c58b","type":"debug","z":"54efb553244c241f","name":"debug 25","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":880,"y":2060,"wires":[]},{"id":"15cb4c8309340734","type":"change","z":"54efb553244c241f","name":"","rules":[{"t":"set","p":"queue","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":420,"y":1960,"wires":[[]]},{"id":"dac58007caf9438b","type":"change","z":"54efb553244c241f","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"queue","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":660,"y":2100,"wires":[["d8eba91018d2c58b"]]},{"id":"e9db8f4747aaf9e2","type":"junction","z":"54efb553244c241f","x":520,"y":2020,"wires":[["3bca06adfd3cf3a0"]]},{"id":"3bca06adfd3cf3a0","type":"junction","z":"54efb553244c241f","x":740,"y":2020,"wires":[["d8eba91018d2c58b"]]},{"id":"17740c7f7eaee224","type":"junction","z":"54efb553244c241f","x":520,"y":2100,"wires":[["dac58007caf9438b"]]},{"id":"0769b75f987235ba","type":"junction","z":"54efb553244c241f","x":280,"y":2060,"wires":[["60849786e5e2203c","15cb4c8309340734"]]}]

```

Every message is stored in flow Context and also being sent to the Trigger node.  
If its the first message it is sent immediately and when the 5 seconds are up the second output of the Trigger node sends a "flush" msg to send whatever is in the queue. You may need a Filter node if you dont want duplicates.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [1 September 2022 11:10 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/46 "2022-09-01T11:10:02Z")

</div>

> [@jbudd](#):
>
> Isn't @dceejay's solution exactly right though?

No, if a new message arrives immediately after the queued one is released then that one is passed through immediately, rather than waiting for another 5 secs. As in the title here it is supposed to operate like a Delay node in Rate Limit, but send the latest message after the delay is up, rather than dropping them or queuing them all.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [1 September 2022 11:14 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/47 "2022-09-01T11:14:16Z")

</div>

> [@UnborN](#):
>
> Every message is stored in flow Context and also being sent to the Trigger node.

I think that one suffers from the same problem. If a message arrives immediately after the flush then it will get straight through.

---

<div class="post-metadata">

### Author: ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)
#### Post date: [1 September 2022 12:13 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/48 "2022-09-01T12:13:22Z")

</div>

If you add a feedback from after the filter to the front of the trigger, then it will block itself again - and not send that message again (loop) due to the filter. There is a v.v.v. small timing gap (the internal node.js loop time) for a message to arrive after the existing message has released and before that feedback happens - that another message could slip through - but it is pretty darn small I think (vs chance of a message turning up any time in the next 5 secs )

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [1 September 2022 13:17 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/49 "2022-09-01T13:17:42Z")

</div>

> [@dceejay](#):
>
> There is a v.v.v. small timing gap (the internal node.js loop time) for a message to arrive after the existing message has released and before that feedback happens - that another message could slip through - but it is pretty darn small I think

Am I right in thinking that after the trigger node sends the message it will service any other nodes that have messages waiting (which might take some time) and then do another pass, which will service the message in the filter node, which will add the message to the queue for the Trigger node. So not that small a window I think. Similar in size to the race windows in other solutions found proposed. It depends how important it is that messages are spaced out correctly. The engineer in me doesn't like to leave such windows open.

---

<div class="post-metadata">

### Author: ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)
#### Post date: [1 September 2022 13:27 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/50 "2022-09-01T13:27:06Z")

</div>

Could you set a incoming rate limit of say 50ms to @dceejay flow, then any race condition would need to be over 50ms.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [1 September 2022 13:36 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/51 "2022-09-01T13:36:55Z")

</div>

Even then there is a small possibility of hitting it, as we are not running on a real time OS so other things can hog the processor, therefore the 50ms could run down while nothing is going on in node-red. Memory management in nodejs could also do it I think. You can't rely 100% on a real-time delay spacing things out in a non-real time system.

Edit: I think that should be 'non real-time', not non-real time. The time is real enough I think. Or perhaps not, difficult to know 🙂

---

<div class="post-metadata">

### Author: ![cameo69](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cameo69/32/66593_2.png) [@cameo69](https://discourse.nodered.org/u/cameo69)
#### Post date: [4 September 2022 15:40 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/52 "2022-09-04T15:40:08Z")

</div>

I think this satisfies your requirements:

```auto
[{"id":"9ebe08998f198b8e","type":"q-gate","z":"8d7193deb1042133","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":"1","keepNewest":true,"qToggle":false,"persist":false,"storeName":"memory","x":350,"y":1480,"wires":[["f7d527ac279b9c72","fd79c46e7aa9f525"]]},{"id":"8bc4aaf3943c0dbb","type":"inject","z":"8d7193deb1042133","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":240,"y":1320,"wires":[["9ebe08998f198b8e","6f7f783c2cd5f727"]]},{"id":"6f7f783c2cd5f727","type":"delay","z":"8d7193deb1042133","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"5","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":680,"y":1320,"wires":[["882ae2a9ad40c8ac"]]},{"id":"882ae2a9ad40c8ac","type":"change","z":"8d7193deb1042133","name":"control + flush","rules":[{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"},{"t":"set","p":"payload","pt":"msg","to":"flush","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":900,"y":1320,"wires":[["9ebe08998f198b8e"]]},{"id":"fd79c46e7aa9f525","type":"debug","z":"8d7193deb1042133","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1110,"y":1480,"wires":[]},{"id":"f7d527ac279b9c72","type":"trigger","z":"8d7193deb1042133","name":"","op1":"","op2":"","op1type":"pay","op2type":"payl","duration":"5","extend":true,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":2,"x":440,"y":1360,"wires":[[],["6f7f783c2cd5f727"]]}]

```

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/e/cef352e4b6e5b8f718703010565ecdbbb8b8f0ab.png)

q-gate always has the last msg queued and the incoming msg themselves create with the limiter the cycles. And since you want the last msg to be sent, a last cycle is triggered after 5 sec after the last send msg. If only one msg was triggered, the flush does not hurt.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [4 September 2022 16:18 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/53 "2022-09-04T16:18:16Z")

</div>

Welcome to the forum @cameo69

That is certainly close. For me it occasionally locks up if I send multiple messages close together but I am not sure why yet.

---

<div class="post-metadata">

### Author: ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)
#### Post date: [4 September 2022 17:44 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/54 "2022-09-04T17:44:04Z")

</div>

With @cameo69's flow it is possible to get a message stuck in the queue:

Inject msg A and after 1s inject MSG B. MSG A emerges immediately, MSG B is in the queue.  
When MSG B emerges from the queue the 5s trigger starts.  
At some point in this 5s window, inject MSG C. It goes in the queue.  
The rate limit prevents the flush operation.

The problem can be automated:

```auto
[{"id":"1e54316d289588c8","type":"q-gate","z":"864772ef56f82916","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":"1","keepNewest":true,"qToggle":false,"persist":false,"storeName":"memory","x":410,"y":1680,"wires":[["c32004fbc8056531","a18df0789a2f53f1"]]},{"id":"7a1a70977035002f","type":"inject","z":"864772ef56f82916","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"MSG A","payloadType":"str","x":110,"y":1600,"wires":[["89b26b6a10d4908f","65df77aa6ce0b183","3898a55a51e5d87f"]]},{"id":"303f91c83bad0fe6","type":"delay","z":"864772ef56f82916","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"5","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":600,"y":1560,"wires":[["68efeacf3b849413"]]},{"id":"68efeacf3b849413","type":"change","z":"864772ef56f82916","name":"control + flush","rules":[{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"},{"t":"set","p":"payload","pt":"msg","to":"flush","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":1560,"wires":[["1e54316d289588c8"]]},{"id":"a18df0789a2f53f1","type":"debug","z":"864772ef56f82916","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":790,"y":1680,"wires":[]},{"id":"c32004fbc8056531","type":"trigger","z":"864772ef56f82916","name":"","op1":"","op2":"","op1type":"pay","op2type":"payl","duration":"5","extend":true,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":2,"x":400,"y":1600,"wires":[[],["303f91c83bad0fe6"]]},{"id":"89b26b6a10d4908f","type":"trigger","z":"864772ef56f82916","name":"1s MSG B","op1":"","op2":"MSG B","op1type":"nul","op2type":"str","duration":"1","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":110,"y":1640,"wires":[["65df77aa6ce0b183"]]},{"id":"3898a55a51e5d87f","type":"trigger","z":"864772ef56f82916","name":"11s MSG C","op1":"","op2":"MSG C","op1type":"nul","op2type":"str","duration":"11","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":110,"y":1560,"wires":[["65df77aa6ce0b183"]]},{"id":"39c30c01ab019180","type":"inject","z":"864772ef56f82916","name":"Reset","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"control","payloadType":"str","x":610,"y":1520,"wires":[["68efeacf3b849413"]]},{"id":"65df77aa6ce0b183","type":"junction","z":"864772ef56f82916","x":240,"y":1560,"wires":[["303f91c83bad0fe6","1e54316d289588c8"]]}]

```

 ![Untitled 1](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/5/252818f133f0d159344cf8a0db055e997e785b12.jpeg)

Can this be fixed by tweeking the trigger and rate limit slightly?

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [4 September 2022 18:47 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/56 "2022-09-04T18:47:26Z")

</div>

Why doesn't the next message coming in flush the gate?

---

<div class="post-metadata">

### Author: ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)
#### Post date: [4 September 2022 18:56 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/57 "2022-09-04T18:56:03Z")

</div>

I can't explain it, I can only reproduce it!

But the next message, _if one arrives_, will indeed release MSG C (I think, not at my pc)

It's a massive 5 second window in which a new message gets stuck. Something is wrong with the combination of trigger and rate limit

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [4 September 2022 19:13 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/58 "2022-09-04T19:13:50Z")

</div>

I can't have another look till tomorrow. I think the first thing to do is to see if a message comes out of the change node when, after the lockup, another message comes in.

---

<div class="post-metadata">

### Author: ![Hopperpop](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hopperpop/32/42533_2.png) [@Hopperpop](https://discourse.nodered.org/u/Hopperpop)
#### Post date: [4 September 2022 20:49 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/59 "2022-09-04T20:49:06Z")

</div>

Is a function node an option? Or you really want to do it with a delay node?

Else you could do something like this in a function node:

```auto
let delay = 5000; //ms

let lastTime = context.get('lastTime') || 0;
let timeout = context.get('timeout') || 0;

let nowTime = Date.now();

if ((nowTime - lastTime) > delay && !timeout){
    //Send directly
    context.set('lastTime', nowTime);
    context.set('timeout',0);
    return msg;
} else {
    //Create timeout if not existing
    if (! timeout){
        let timeout = setTimeout(() => {
            //On timeout, grap last message, send and clear data
            let msg = context.get('bufferMsg') || null;
            context.set('lastTime', Date.now());
            context.set('timeout', 0 );
            context.set('bufferMsg',null);
            if(msg){
                node.send(msg);
            }
        }, delay - (nowTime - lastTime));
        context.set('timeout',timeout);
    }

    //Buffer last message
    context.set('bufferMsg', msg);
}

```

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [4 September 2022 20:55 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/60 "2022-09-04T20:55:34Z")

</div>

> [@Hopperpop](#):
>
> Is a function node an option?

Yes, of course. That is the fallback if it cannot be done reasonably easily otherwise.

---

<div class="post-metadata">

### Author: ![cameo69](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cameo69/32/66593_2.png) [@cameo69](https://discourse.nodered.org/u/cameo69)
#### Post date: [4 September 2022 21:17 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/61 "2022-09-04T21:17:01Z")

</div>

@Colin, a plain function node has been proposed.  
But if you are willing to use a state machine (e.g. node-red-contrib-xstate-machine) things get easy.

```auto
[{"id":"0307ecee22b66ef9","type":"smxstate","z":"8d7193deb1042133","name":"","xstateDefinition":"// Available variables/objects/functions:\n// xstate\n// - .Machine\n// - .interpret\n// - .assign\n// - .send\n// - .sendParent\n// - .spawn\n// - .raise\n// - .actions\n//\n// Common\n// - setInterval, setTimeout, clearInterval, clearTimeout\n// - node.send, node.warn, node.log, node.error\n// - context.get, context.set\n// - flow.get, flow.set\n// - env.get\n// - util\n\nconst { assign } = xstate;\n\n// First define names guards, actions, ...\n\n/**\n * Guards\n */\nconst isCounterZero = (context, event) => {\n return context.counter == 0;\n};\n\n/**\n * Actions\n */\nconst incrementCounter = assign({\n counter: (context, event) => 1\n});\n\nconst zeroCounter = assign({\n counter: (context, event) => 0\n});\n\n\nconst sendTrigger = assign({\n counter: (context, event) => {\n // Can send log messages via\n // - node.log\n // - node.warn\n // - node.error\n //node.warn(\"RESET\");\n\n // Can send messages to the second outport\n // Specify an array to send multiple messages\n // at once\n // - node.send(msg)\n node.send({ topic: \"control\", payload: \"trigger\" });\n\n return 0;\n }\n});\n\n\n/ ***************************\n * Main machine definition * \n*************************** /\nreturn {\n machine: {\n predictableActionArguments: true,\n context: {\n counter: 0\n },\n initial: 'idle',\n states: {\n idle: {\n on: {\n incoming: { target: 'trigger' }\n }\n },\n trigger: {\n entry: ['sendTrigger', 'zeroCounter'],\n on: {\n incoming: { actions: 'incrementCounter' },\n '': { target: 'wait' }\n }\n },\n wait: {\n on: {\n incoming: { actions: 'incrementCounter' }\n },\n after: {\n 5000: [{ target: 'last', cond: 'isCounterZero' },\n { target: 'trigger' }]\n }\n },\n last: {\n entry: ['sendTrigger', 'zeroCounter'],\n on: {\n incoming: { actions: 'incrementCounter' },\n '': [{ target: 'idle', cond: 'isCounterZero' },\n { target: 'wait' }]\n }\n }\n }\n },\n // Configuration containing guards, actions, activities, ...\n // see above\n config: {\n guards: { isCounterZero },\n actions: { incrementCounter, sendTrigger, zeroCounter },\n activities: {}\n },\n // Define listeners (can be an array of functions)\n // Functions get called on every state/context update\n listeners: (data) => {\n //node.warn(data.state + \":\" + data.context.counter);\n }\n};","noerr":0,"x":740,"y":2980,"wires":[[],["df7cc341b1b286ef"]]},{"id":"477d97d9cbf08b23","type":"inject","z":"8d7193deb1042133","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":260,"y":2940,"wires":[["101d713325575ffc"]]},{"id":"68d3cf9c811f6ad4","type":"debug","z":"8d7193deb1042133","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":730,"y":3080,"wires":[]},{"id":"df7cc341b1b286ef","type":"q-gate","z":"8d7193deb1042133","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":"1","keepNewest":true,"qToggle":false,"persist":false,"storeName":"memory","x":550,"y":3080,"wires":[["68d3cf9c811f6ad4"]]},{"id":"c85c02f985c5ea4e","type":"change","z":"8d7193deb1042133","name":"topic = incoming","rules":[{"t":"set","p":"topic","pt":"msg","to":"incoming","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":530,"y":2980,"wires":[["0307ecee22b66ef9"]]},{"id":"7a1a70977035002f","type":"inject","z":"8d7193deb1042133","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"MSG A","payloadType":"str","x":250,"y":3080,"wires":[["89b26b6a10d4908f","65df77aa6ce0b183","3898a55a51e5d87f"]]},{"id":"89b26b6a10d4908f","type":"trigger","z":"8d7193deb1042133","name":"1s MSG B","op1":"","op2":"MSG B","op1type":"nul","op2type":"str","duration":"1","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":250,"y":3120,"wires":[["65df77aa6ce0b183"]]},{"id":"3898a55a51e5d87f","type":"trigger","z":"8d7193deb1042133","name":"11s MSG C","op1":"","op2":"MSG C","op1type":"nul","op2type":"str","duration":"11","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":250,"y":3040,"wires":[["65df77aa6ce0b183"]]},{"id":"65df77aa6ce0b183","type":"junction","z":"8d7193deb1042133","x":380,"y":3040,"wires":[["101d713325575ffc"]]},{"id":"101d713325575ffc","type":"junction","z":"8d7193deb1042133","x":400,"y":2980,"wires":[["df7cc341b1b286ef","c85c02f985c5ea4e"]]}]

```

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/0/809335674aab5e903e9b2605e68bf86c5628b94e.png)

This is including the case found by @jbudd.

---

<div class="post-metadata">

### Author: ![drmibell](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/drmibell/32/8424_2.png) [@drmibell](https://discourse.nodered.org/u/drmibell)
#### Post date: [4 September 2022 21:28 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/62 "2022-09-04T21:28:23Z")

</div>

As author of the `q-gate` node, I want to help out here, but I have been too busy to follow the discussion in any depth. Based on the original post, I think this flow meets the requirements without the possibility of race conditions. (See this [discussion](https://discourse.nodered.org/t/close-gate-after-one-message-has-passed-through/56575/7) and [this one](https://discourse.nodered.org/t/timing-question-avoiding-race-conditions/55616).)

 ![Untitled](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/d/fdf420fbdb64b10d4db8fc94d0553d6be80a82c2.jpeg)

```auto
[{"id":"67659f7786234008","type":"inject","z":"0ae9d1938fe1cb0d","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"2","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":80,"wires":[["e8de0d8f5c30616b","92b84dfdf699239e"]]},{"id":"e8de0d8f5c30616b","type":"function","z":"0ae9d1938fe1cb0d","name":"queue after","func":"return [[msg,{payload:'queue',topic:'control'}]]","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":80,"wires":[["c453ff7e92e4428d"]]},{"id":"92b84dfdf699239e","type":"trigger","z":"0ae9d1938fe1cb0d","name":"open after 5s","op1":"","op2":"open","op1type":"nul","op2type":"str","duration":"5","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":310,"y":120,"wires":[["1354ec7ffed7352c"]]},{"id":"c453ff7e92e4428d","type":"q-gate","z":"0ae9d1938fe1cb0d","name":"","controlTopic":"control","defaultState":"open","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","queueCmd":"queue","defaultCmd":"default","triggerCmd":"trigger","flushCmd":"flush","resetCmd":"reset","peekCmd":"peek","dropCmd":"drop","statusCmd":"status","maxQueueLength":"1","keepNewest":true,"qToggle":false,"persist":false,"storeName":"memory","x":650,"y":80,"wires":[["1248d518fe22581f"]]},{"id":"1354ec7ffed7352c","type":"change","z":"0ae9d1938fe1cb0d","name":"topic:control","rules":[{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":120,"wires":[["c453ff7e92e4428d"]]},{"id":"1248d518fe22581f","type":"debug","z":"0ae9d1938fe1cb0d","name":"debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":770,"y":80,"wires":[]}]

```

I could easily be mistaken, so if anyone can demonstrate a race condition here, either in theory or practice, please let me know.

---

<div class="post-metadata">

### Author: ![cameo69](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cameo69/32/66593_2.png) [@cameo69](https://discourse.nodered.org/u/cameo69)
#### Post date: [4 September 2022 21:45 UTC](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170/63 "2022-09-04T21:45:57Z")

</div>

Hi @drmibell, I think i does not meet the requirements.  
Just clicking quickly on the trigger button I got msg quicker than 5s. Here is an example:

```auto
[{"id":"67659f7786234008","type":"inject","z":"8d7193deb1042133","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":360,"y":3940,"wires":[["86fe5414cef4edd6","9b9b63b53aa3f5cc","d46cb9e075df54a5"]]},{"id":"e8de0d8f5c30616b","type":"function","z":"8d7193deb1042133","name":"queue after","func":"return [[msg,{payload:'queue',topic:'control'}]]","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":710,"y":3960,"wires":[["c453ff7e92e4428d"]]},{"id":"92b84dfdf699239e","type":"trigger","z":"8d7193deb1042133","name":"open after 5s","op1":"","op2":"open","op1type":"nul","op2type":"str","duration":"5","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":630,"y":4000,"wires":[["1354ec7ffed7352c"]]},{"id":"c453ff7e92e4428d","type":"q-gate","z":"8d7193deb1042133","name":"","controlTopic":"control","defaultState":"open","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","queueCmd":"queue","defaultCmd":"default","triggerCmd":"trigger","flushCmd":"flush","resetCmd":"reset","peekCmd":"peek","dropCmd":"drop","statusCmd":"status","maxQueueLength":"1","keepNewest":true,"qToggle":false,"persist":false,"storeName":"memory","x":970,"y":3960,"wires":[["1248d518fe22581f"]]},{"id":"1354ec7ffed7352c","type":"change","z":"8d7193deb1042133","name":"topic:control","rules":[{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":4000,"wires":[["c453ff7e92e4428d"]]},{"id":"1248d518fe22581f","type":"debug","z":"8d7193deb1042133","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1210,"y":3960,"wires":[]},{"id":"9b9b63b53aa3f5cc","type":"trigger","z":"8d7193deb1042133","name":"4s","op1":"","op2":"","op1type":"nul","op2type":"date","duration":"4","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":350,"y":3980,"wires":[["86fe5414cef4edd6"]]},{"id":"d46cb9e075df54a5","type":"trigger","z":"8d7193deb1042133","name":"5001 ms","op1":"","op2":"","op1type":"nul","op2type":"date","duration":"5001","extend":false,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":360,"y":4020,"wires":[["86fe5414cef4edd6"]]},{"id":"86fe5414cef4edd6","type":"junction","z":"8d7193deb1042133","x":520,"y":3960,"wires":[["e8de0d8f5c30616b","92b84dfdf699239e"]]}]

```

 ![Pasted Graphic 2](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/f/3ff8307789d80f8b430aefbf5febbd9b4ab0f6d6.png)

Quickly tested this scenario with the state machine and it passed.

[Previous page](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170.md?page=2)

[Next page](https://discourse.nodered.org/t/can-the-delay-node-rate-limit-but-pass-first-message-immediately-and-always-pass-on-the-latest-message/67170.md?page=4)
