A re-imagining of the delay node (subflow)

I recently tried using the delay node to rate-limit messages to 1 per day. I had expected the first message to pass immediately, but quickly learned that it holds onto messages that pass until a static interval is reached. So I decided to create a rate limiting subflow. I thought I would share that subflow and ask if anyone else may have a node or similar subflow that may home done it differently from me and what features may differ...

I decided to allow the user to hook into the same timer in different instances by having them set a global variable property. It would be nice though if the default value was a random string so that you're not required to change it unless you explicitly wanted to instances to use the same timer... Any thoughts?

[{"id":"6c0c6334.d0b9dc","type":"subflow","name":"Rate Limit","info":"Initial messages into this flow will immediately pass.  Subsequent messages within the set duration (starting after the first passed message) will be skipped.\n\nMultiple subflow instances can use the same timer by setting the same global variable to use.  If the value of the variable is true, it means any previous timer has expired and the next message will pass.  If it is false, the subflow node will not emit the message (i.e. the message is destroyed).","category":"","in":[{"x":40,"y":80,"wires":[{"id":"1a792ee.e56b151"}]}],"out":[{"x":400,"y":40,"wires":[{"id":"2b21c309.d928bc","port":0}]}],"env":[{"name":"waittime","type":"num","value":"10","ui":{"icon":"font-awesome/fa-hourglass-2","label":{"en-US":"Wait time"},"type":"spinner"}},{"name":"waitunits","type":"str","value":"s","ui":{"icon":"font-awesome/fa-pie-chart","label":{"en-US":"Units"},"type":"select","opts":{"opts":[{"l":{"en-US":"seconds"},"v":"s"},{"l":{"en-US":"minutes"},"v":"m"},{"l":{"en-US":"hours"},"v":"h"},{"l":{"en-US":"days"},"v":"d"}]}}},{"name":"timername","type":"str","value":"rate_limit_name","ui":{"icon":"font-awesome/fa-tag","label":{"en-US":"Global Timer Variable Name to Use"}}}],"color":"#DDAA99"},{"id":"fae935cc.e514d","type":"delay","z":"6c0c6334.d0b9dc","name":"timer","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":710,"y":120,"wires":[["1aab977c.c9ae91"]]},{"id":"1ee8e599.d93e12","type":"change","z":"6c0c6334.d0b9dc","name":"Calc Secs","rules":[{"t":"set","p":"delay","pt":"msg","to":"$env('waittime') * 1000","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":60,"wires":[["fae935cc.e514d"]]},{"id":"a187ff72.d593","type":"switch","z":"6c0c6334.d0b9dc","name":"wait","property":"waitunits","propertyType":"env","rules":[{"t":"eq","v":"s","vt":"str"},{"t":"eq","v":"m","vt":"str"},{"t":"eq","v":"h","vt":"str"},{"t":"eq","v":"d","vt":"str"},{"t":"else"}],"checkall":"false","repair":false,"outputs":5,"x":430,"y":120,"wires":[["1ee8e599.d93e12"],["ce17b590.337ae"],["25e3671d.ddb368"],["256d77b6.80925"],["a99d1a6a.e11d68"]]},{"id":"ce17b590.337ae","type":"change","z":"6c0c6334.d0b9dc","name":"Calc Mins","rules":[{"t":"set","p":"delay","pt":"msg","to":"$env('waittime') * 1000 * 60","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":100,"wires":[["fae935cc.e514d"]]},{"id":"25e3671d.ddb368","type":"change","z":"6c0c6334.d0b9dc","name":"Calc Hrs","rules":[{"t":"set","p":"delay","pt":"msg","to":"$env('waittime') * 1000 * 60 * 60","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":140,"wires":[["fae935cc.e514d"]]},{"id":"256d77b6.80925","type":"change","z":"6c0c6334.d0b9dc","name":"Calc Dys","rules":[{"t":"set","p":"delay","pt":"msg","to":"$env('waittime') * 1000 * 60 * 60 * 24","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":180,"wires":[["fae935cc.e514d"]]},{"id":"6f982be.34e9fd4","type":"debug","z":"6c0c6334.d0b9dc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":690,"y":220,"wires":[]},{"id":"2b21c309.d928bc","type":"function","z":"6c0c6334.d0b9dc","name":"set wait to true","func":"global.set(env.get(\"timername\"), true);\nreturn msg;","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is deployed.\nglobal.set(env.get(\"timername\"), false);\n","finalize":"","x":280,"y":80,"wires":[["a187ff72.d593"]]},{"id":"1a792ee.e56b151","type":"function","z":"6c0c6334.d0b9dc","name":"skip?","func":"let mywait = false;\nif(global.get(env.get(\"timername\"))!==undefined)\n  mywait = global.get(env.get(\"timername\"));\nif(!mywait)\n  return msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":130,"y":80,"wires":[["2b21c309.d928bc"]]},{"id":"1aab977c.c9ae91","type":"function","z":"6c0c6334.d0b9dc","name":"set wait to true","func":"global.set(env.get(\"timername\"), false);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":860,"y":120,"wires":[[]]},{"id":"a99d1a6a.e11d68","type":"template","z":"6c0c6334.d0b9dc","name":"Error","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"Invalid rate limit units set in subflow properties: {{{waitunits}}}","output":"str","x":550,"y":220,"wires":[["6f982be.34e9fd4"]]}]

I think if the delay node is in all messages mode rather than per topic it should send the first message right away.

Hmm. I never use per topic and always use all messages. I'd set a 1 day delay so that I'd only ever get a message within 24h of a previous message, but when I tested it, nothing ever got through. Maybe I made a mistake. I'll test it again.

Indeed you're right. Must have made a mistake originally.

Would a Trigger node work for you to. You could input delay and have per topic.

[{"id":"77ec80a1.c64fe8","type":"inject","z":"c791cbc0.84f648","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"topic1","payload":"","payloadType":"date","x":160,"y":380,"wires":[["f618c976.db9ef"]]},{"id":"f618c976.db9ef","type":"trigger","z":"c791cbc0.84f648","name":"","op1":"","op2":"reset","op1type":"pay","op2type":"str","duration":"10000","extend":false,"overrideDelay":true,"units":"ms","reset":"reset","bytopic":"topic","topic":"topic","outputs":2,"x":360,"y":440,"wires":[["79ad0502.f1816c"],["2dcf96ea.a9e55a"]]},{"id":"2dcf96ea.a9e55a","type":"change","z":"c791cbc0.84f648","name":"","rules":[],"action":"","property":"","from":"","to":"","reg":false,"x":495,"y":440,"wires":[["f618c976.db9ef"]],"l":false},{"id":"3cf3294.0631fd6","type":"inject","z":"c791cbc0.84f648","name":"with msg.delay","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"delay","v":"5000","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"topic2","payload":"","payloadType":"date","x":170,"y":500,"wires":[["f618c976.db9ef"]]},{"id":"79ad0502.f1816c","type":"debug","z":"c791cbc0.84f648","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":610,"y":380,"wires":[]}]

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