# Super simple round-robin router implemented in a function node

**URL:** https://discourse.nodered.org/t/super-simple-round-robin-router-implemented-in-a-function-node/89737
**Category:** Share Your Nodes
**Tags:** function-node
**Created:** [24 July 2024 19:46 UTC](https://discourse.nodered.org/t/super-simple-round-robin-router-implemented-in-a-function-node/89737 "2024-07-24T19:46:15Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Semmu](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/semmu/32/31164_2.png) [@Semmu](https://discourse.nodered.org/u/Semmu)
#### Post date: [24 July 2024 19:46 UTC](https://discourse.nodered.org/t/super-simple-round-robin-router-implemented-in-a-function-node/89737/1 "2024-07-24T19:46:15Z")

</div>

Hello everyone,

The other day I was looking for a simple round-robin node that could forward the received messages to different destinations based on a simple counter. An example usage of this could be (in a smarthome context) a button, which on first press turns on the light, then dims it, then for the third press turns it off. (Then the cycle repeats of course.) This is a 3-state round-robin loop, but you could have one with only 2 states (on-off basically) or as many as you need.

I found [node-red-contrib-round-robin](https://flows.nodered.org/node/node-red-contrib-round-robin), but its source repository seems gone, so I did not feel like using it, and also found [node-red-contrib-msg-router](https://flows.nodered.org/node/node-red-contrib-msg-router), which supports round-robin routing, but seems like a heavy-weight solution, so I also did not feel like using that.

So I just implemented it in a custom function node! Here is the source:

```auto
const previous = (typeof context.get('localCounter') === 'undefined' ? -1 : context.get('localCounter'));
const current = (typeof msg._set === 'number' ? msg._set : previous + 1) % node.outputCount;

context.set('localCounter', current)

node.status({
    fill: 'green',
    shape: 'ring',
    text: `${current+1}/${node.outputCount}`
});

const msgs = [];
msgs[current] = msg;

return msgs;

```

You just basically need to copy this snippet into a function node and set the desired output count for the node and that's it!

Each instance of this function node remembers its local counter via context, and defaults to sending the first message to the first output.

It also supports forcing the output (basically setting the counter by hand) if the received message has a `msg._set` number property. It is a 0-based number, keep that in mind!

And lastly, it also displays the counter for the last message and the total output number as a node state in the editor.

Hope it helps anyone!

---

<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: [24 July 2024 20:08 UTC](https://discourse.nodered.org/t/super-simple-round-robin-router-implemented-in-a-function-node/89737/2 "2024-07-24T20:08:01Z")

</div>

> [@Semmu](#):
>
> `const previous = (typeof context.get('localCounter') === 'undefined' ? -1 : context.get('localCounter'));`

Just a note that this can be simplified using the snappily named ' Nullish coalescing operator (??)'

`const previous = context.get('localCounter') ?? -1`

---

<div class="post-metadata">

### Author: ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)
#### Post date: [24 July 2024 20:26 UTC](https://discourse.nodered.org/t/super-simple-round-robin-router-implemented-in-a-function-node/89737/3 "2024-07-24T20:26:02Z")

</div>

If you are using MQTT you can also achieve this for free using shared topics.

> [@Redundant node-red instances plugged on AWS IOT CORE](https://discourse.nodered.org/t/redundant-node-red-instances-plugged-on-aws-iot-core/45856/2):
>
> In pretty sure you can use mqtt shared subscriptions anywhere with v5 mqtt broker. Just give it a go. Node-red 1 Subscribe to $share/group1/test Node-red 2 Subscribe to $share/group1/test Node-red 3 Publish to test You should only get a message to one or the other.

> **[MQTT Shared Subscriptions – MQTT 5 Essentials Part 7](https://www.hivemq.com/blog/mqtt5-essentials-part7-shared-subscriptions/#heading-mqtt-shared-subscriptions-mqtt-5-essentials-part-7)**
>
> Learn how to improve load balancing & fault tolerance using MQTT 5 Shared subscriptions that enable multiple MQTT clients to share a single subscription.

---

<div class="post-metadata">

### Author: ![Semmu](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/semmu/32/31164_2.png) [@Semmu](https://discourse.nodered.org/u/Semmu)
#### Post date: [26 July 2024 12:33 UTC](https://discourse.nodered.org/t/super-simple-round-robin-router-implemented-in-a-function-node/89737/4 "2024-07-26T12:33:07Z")

</div>

Hey @Colin thanks for the suggestion, I forgot about that operator! Makes it simpler indeed.

@Steve-Mcl thanks for this link, I didn't know about this MQTT feature! But I also want to keep all my logic within NR itself, and I need this router for non-MQTT related stuff too, so that's why I chose to implement it within a function node.

---

<div class="post-metadata">

### Author: ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)
#### Post date: [30 July 2024 14:05 UTC](https://discourse.nodered.org/t/super-simple-round-robin-router-implemented-in-a-function-node/89737/5 "2024-07-30T14:05:04Z")

</div>

Glad you found a low-code solution!

In the spirit of providing another (essentially) no-code way to route messages via a counter, I have also used [this technique](https://discourse.nodered.org/t/switch-node-jsonata-magic/12943/4) based on a `switch` node:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/9/96cb3b46dd43523c3380f6ce7ab22e4166ae94d1.png)

Of course, it doesn't provide the nice status message, but it's useful when you just need to send a message down a different path, say for a poor-man's load-balancer.
