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.
This commit is contained in:
David Négrier 2020-12-14 22:20:43 +01:00
parent 7e2e530f9f
commit aeb5dc7922

View File

@ -3,17 +3,30 @@
*/ */
import {RoomManagerClient} from "../Messages/generated/messages_grpc_pb"; import {RoomManagerClient} from "../Messages/generated/messages_grpc_pb";
import grpc from 'grpc'; import grpc from 'grpc';
import crypto from 'crypto';
import {API_URL} from "../Enum/EnvironmentVariable"; import {API_URL} from "../Enum/EnvironmentVariable";
import Debug from "debug";
const debug = Debug('apiClientRespository');
class ApiClientRepository { class ApiClientRepository {
private roomManagerClient: RoomManagerClient|null = null; private roomManagerClients: RoomManagerClient[] = [];
public constructor(private apiUrls: string[]) {
}
public async getClient(roomId: string): Promise<RoomManagerClient> { public async getClient(roomId: string): Promise<RoomManagerClient> {
if (this.roomManagerClient === null) { const array = new Uint32Array(crypto.createHash('md5').update(roomId).digest());
this.roomManagerClient = new RoomManagerClient(API_URL, grpc.credentials.createInsecure()); 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<RoomManagerClient[]> { public async getAllClients(): Promise<RoomManagerClient[]> {
@ -21,6 +34,6 @@ class ApiClientRepository {
} }
} }
const apiClientRepository = new ApiClientRepository(); const apiClientRepository = new ApiClientRepository(API_URL.split(','));
export { apiClientRepository }; export { apiClientRepository };