dashersw/cote

Requester-Responder Round-Robin Load-Balancing Doesn't Work

ashih42 opened this issue · 7 comments

I tried running 1 Requester and 2 Responders on the same machine on 3 terminals. I sent 5 requests, but all 5 requests were handled by one Responder, instead of being split evenly among all Responders.

I modified the example scripts as shown below:

Requester in time-client.js:

const cote = require("cote");
const client = new cote.Requester({ name: "Client" });

function send_request() {
  client.send({ type: "time" }, (time) => {
    console.log(time);
  });
}

for (let i = 0; i < 5; i++) {
  send_request();
}

Responder in time-service.js:

const cote = require("cote");
const timeService = new cote.Responder({ name: "Time Service" });

timeService.on("time", (req, cb) => {
  console.log("Generating time...");
  cb(new Date());
});

I start the 2 Responders first. It looks like the 2 Responders have discovered each other.

In Terminal 1 (Responder 1):

~/cote-example$ node time-service.js

Hello! I'm Time Service#649b3d77-3968-4ba4-9a49-aa923cf66166 on 8000
========================

Time Service > service.online Time Service#43b19797-2563-42fe-bae2-0a5662cbe366 on 8000

In Terminal 2 (Responder 2):

~/cote-example$ node time-service.js

Hello! I'm Time Service#43b19797-2563-42fe-bae2-0a5662cbe366 on 8000
========================

Time Service > service.online Time Service#649b3d77-3968-4ba4-9a49-aa923cf66166 on 8000

Now I run the Requester, sending 5 requests.

In Terminal 1 (Responder 1):

~/cote-example$ node time-service.js

Hello! I'm Time Service#649b3d77-3968-4ba4-9a49-aa923cf66166 on 8000
========================

Time Service > service.online Time Service#43b19797-2563-42fe-bae2-0a5662cbe366 on 8000
Time Service > service.online Client#da873605-dfc2-430f-a3e1-398011ab5105
Generating time...
Generating time...
Generating time...
Generating time...
Generating time...

This Responder handled all 5 requests.

In Terminal 2 (Responder 2):

~/cote-example$ node time-service.js

Hello! I'm Time Service#43b19797-2563-42fe-bae2-0a5662cbe366 on 8000
========================

Time Service > service.online Time Service#649b3d77-3968-4ba4-9a49-aa923cf66166 on 8000
Time Service > service.online Client#da873605-dfc2-430f-a3e1-398011ab5105

This Responder handled no requests.

In Terminal 3 (Requester):

~/cote-example$ node time-client.js

Hello! I'm Client#da873605-dfc2-430f-a3e1-398011ab5105
========================

Client > service.online Time Service#43b19797-2563-42fe-bae2-0a5662cbe366 on 8000
2020-06-06T20:23:17.044Z
2020-06-06T20:23:17.045Z
2020-06-06T20:23:17.046Z
2020-06-06T20:23:17.046Z
2020-06-06T20:23:17.047Z
Client > service.online Time Service#649b3d77-3968-4ba4-9a49-aa923cf66166 on 8000

Please let me know if this is really an issue, or I misunderstood something.

@ashih42 I'm guessing this is a timing issue. You are creating the requester and sending 5 messages immediately. Once the requester finds the first responder it shoots the 5 messages over to it before finding any more responders.

To check if this theory is correct, you could put a 5-10 second timeout before you send the requests.

@otothea I modified time-client.js to send 5 requests with 10 second delay between each request.

const cote = require("cote");
const client = new cote.Requester({ name: "Client" });

function send_request() {
  console.log("send_request()");
  client.send({ type: "time" }, (time) => {
    console.log(time);
  });
}

for (let i = 0; i < 5; i++) {
  const delay = i * 10000; // i * 10 seconds
  setTimeout(send_request, delay);
}

The result is the same. One Responder handles all 5 requests. Moreover, you can see the Requester did discover 2 Responders in the log below.

Terminal 3 (Requester):

~/cote-example$ node time-client.js

Hello! I'm Client#03b78528-1422-4f76-ba1e-15ef02c721b3
========================

send_request()
Client > service.online Time Service#d335a8a1-f916-4552-95d9-8ef9725ff7d1 on 8000
2020-06-06T20:53:49.222Z
Client > service.online Time Service#6946bf14-ea9b-4914-8046-81264144b401 on 8000
send_request()
2020-06-06T20:53:58.020Z
send_request()
2020-06-06T20:54:08.019Z
send_request()
2020-06-06T20:54:18.021Z
send_request()
2020-06-06T20:54:28.021Z

Are you on Windows, by any chance? The ports are all 8000 — that's probably why this is failing. They should all have been different ports, e.g. (8000, 8001, 8002).

@dashersw I ran this on WSL Ubuntu. How can I explicitly set the port on my Responders?

a good way to set it is to write it in advertisement options:

const client = new cote.Requester({ name: "Client", port: 8003 });

Yes! I got the 2 Responders to share the workload now after I did these 2 things:

  1. Explicitly set port for each Responder.
  2. Add about 2 seconds delay in time-client.js, before sending all requests.

Thanks for the help, everyone!

glad that you got it working. this shouldn't be an issue in production.