From aeb5dc79225f466f488bf1bcdf820253116a8299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 14 Dec 2020 22:20:43 +0100 Subject: [PATCH] Add scaling capability to the API servers with this one weird trick :) This allows spreading rooms on different API servers based on room name. Note this does provide neither autoscaling nor high availability, but it provides some kind of load balancing. --- pusher/src/Services/ApiClientRepository.ts | 23 +++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/pusher/src/Services/ApiClientRepository.ts b/pusher/src/Services/ApiClientRepository.ts index d5af9e4b..251b123a 100644 --- a/pusher/src/Services/ApiClientRepository.ts +++ b/pusher/src/Services/ApiClientRepository.ts @@ -3,17 +3,30 @@ */ import {RoomManagerClient} from "../Messages/generated/messages_grpc_pb"; import grpc from 'grpc'; +import crypto from 'crypto'; import {API_URL} from "../Enum/EnvironmentVariable"; +import Debug from "debug"; + +const debug = Debug('apiClientRespository'); class ApiClientRepository { - private roomManagerClient: RoomManagerClient|null = null; + private roomManagerClients: RoomManagerClient[] = []; + + public constructor(private apiUrls: string[]) { + } public async getClient(roomId: string): Promise { - if (this.roomManagerClient === null) { - this.roomManagerClient = new RoomManagerClient(API_URL, grpc.credentials.createInsecure()); + const array = new Uint32Array(crypto.createHash('md5').update(roomId).digest()); + const index = array[0] % this.apiUrls.length; + + let client = this.roomManagerClients[index]; + if (client === undefined) { + this.roomManagerClients[index] = client = new RoomManagerClient(this.apiUrls[index], grpc.credentials.createInsecure()); + debug('Mapping room %s to API server %s', roomId, this.apiUrls[index]) } - return Promise.resolve(this.roomManagerClient); + + return Promise.resolve(client); } public async getAllClients(): Promise { @@ -21,6 +34,6 @@ class ApiClientRepository { } } -const apiClientRepository = new ApiClientRepository(); +const apiClientRepository = new ApiClientRepository(API_URL.split(',')); export { apiClientRepository };