Time based Ratelimit / Throttle per topic
Defaults to 10 minutes, override with msg.ratelimitms
(or edit the node)
Defaults to requiring 2 hits within the defined time frame to pass on, override with msg.countToTrigger
(or edit node)
Groups by msg.topic
(one counter per topic).
Discards messages (per topic) until timeout reached.
Designed for reusable flows, such as a notification system that should only notify once per problem type (topic) each 10 minutes.
[{"id":"5b24df49.412f6","type":"function","z":"136ed48.14e8c2c","name":"Rate Limiter","func":"// Defaults to 10 minutes, overridable with msg.ratelimitms\n// Will limit per topic (including by null ones)\nvar interval = msg.ratelimitms || (1000*60*10); // minimum interval between messages (ms)\nvar countToTrigger = msg.countToTrigger || 2;\nvar lastReleasedKey = \"lastReleased_\" + (msg.topic.replace(/ /g, \"_\") || \"null_topic\");\nvar lastHitKey = \"lastHit_\" + (msg.topic.replace(/ /g, \"_\") || \"null_topic\");\nvar cntKey = \"count_\" + (msg.topic.replace(/ /g, \"_\") || \"null_topic\");\nvar lastReleased = (context.get(lastReleasedKey) || 0);\nvar lastHit = (context.get(lastHitKey) || 0);\nvar now = Date.now();\nif (now-lastHit > interval) {\n node.warn(\"resetting count, too far apart.\");\n context.set(cntKey,0); // Clear hits, too far apart.\n}\ncontext.set(lastHitKey,now);\nif (now-lastReleased > interval) {\n var count = (context.get(cntKey) || 0);\n count++;\n if (count >= countToTrigger) {\n context.set(lastReleasedKey,now);\n context.set(cntKey,0);\n node.status({fill:\"green\",shape:\"ring\",text:\"passed on\"});\n return msg;\n } else {\n node.status({fill:\"red\",shape:\"ring\",text:\"Waiting for \" + \n (countToTrigger - count) + \" more hits.\"});\n context.set(cntKey,count);\n return null;\n }\n} else {\n var timeLeft = (interval - (now-lastReleased)) / 1000; \n node.status({fill:\"red\",shape:\"ring\",text:\"blocked for \" + timeLeft + \" seconds\"});\n return null;\n}","outputs":1,"noerr":0,"x":845.0173416137695,"y":274.01039695739746,"wires":[["218e2c7f.b39ab4","a759593e.6deeb8"]]}]