uNetworking / uWebSockets.js

μWebSockets for Node.js back-ends :metal:
Apache License 2.0
7.86k stars 569 forks source link

Scaling PubSub #798

Closed yovanoc closed 1 year ago

yovanoc commented 2 years ago

Hello,

I have a question. How can we scale pubsub properly?

Context:

First, I use cluster or worker_threads for scaling. But There is a need to tell the main process to propagate because each process have his own uWebSockets app, kinda like this:

main process:


  cluster.on("message", async (child, data) => {
    if (
      ["broadcast"].includes(
        data.type
      )
    ) {
      for (const worker of Object.values(clusterMain.workers ?? [])) {
        worker?.send(data);
      }
    }
    // other things
  });

export async function broadcast(
  message: Message,
  topic = "broadcast"
) {
  const messageBuffer = messageToBuffer(message);

  if (topic !== "broadcast") {
    cluster.worker?.send({
      type: "broadcast",
      topic,
      messageBuffer
    });
  } else {
    app.publish(topic, messageBuffer, true, true);
  }
}

workers

cluster.worker?.on("message", data => {
  switch (data.type) {
    case "broadcast": {
      app.publish(data.topic, Buffer.from(data.messageBuffer), true, true);
      break;
    }
    default:
      break;
  }
});

But for debugging purposes I start to think that I can remove clustering in development to add a debugger to the process, then, do the horizontal scaling with Kubernetes, but the same problem will occur too.

So my question is, if there is a way to have a proper production scaling but without letting pubsub on the side.

Thanks !

e3dio commented 2 years ago

I would try to help but I am confused what exactly you are asking, what do you mean "without letting pubsub on the side" ?

e3dio commented 2 years ago

Your options are add more threads and/or add more servers, you can test to determine what combination is best for your app, you are suggesting you want single thread because it will simplify your app/debugging, that is probably fine, cloud providers charge per vCPU so adding thread on same machine cost same as adding thread on new server

yovanoc commented 2 years ago

Yeah but the pubsub inside uWebSockets won't work if we create more instances inside k8s for example. We have to add a layer on top of that, because each instance have its own app and list of connected clients, I'm looking for a proper way to scale and have pubsub working without too much trouble

e3dio commented 2 years ago

Ok so your question is how to send messages between instances/servers, yes that is something you need to set up, not really that hard, broadcast to each other server what topic and what message to send. If you have groups of servers in different geographic regions you would broadcast message to each region, each region broadcasts message to each server

joshxyzhimself commented 1 year ago

The way I see it, it depends on the needs of your app:

There were plans before on having something like those being built-in within uws but I don't think it really pushed through. (can someone confirm lol)