From 4a481acca68200d62e52a39b75edf77daf590971 Mon Sep 17 00:00:00 2001 From: Tom Vincent <github@tlvince.com> Date: Wed, 3 Jul 2024 21:27:29 +0100 Subject: [PATCH] fix(server): Postgres -> Redis websocket (#10801) --- server/package-lock.json | 118 ++++++++++++++------- server/package.json | 2 +- server/src/config.ts | 2 +- server/src/middleware/websocket.adapter.ts | 11 +- 4 files changed, 86 insertions(+), 47 deletions(-) diff --git a/server/package-lock.json b/server/package-lock.json index 51b691cdaa..cb53bb2117 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -25,7 +25,7 @@ "@opentelemetry/exporter-prometheus": "^0.52.0", "@opentelemetry/sdk-node": "^0.52.0", "@react-email/components": "^0.0.19", - "@socket.io/postgres-adapter": "^0.3.1", + "@socket.io/redis-adapter": "^8.3.0", "archiver": "^7.0.0", "async-lock": "^1.4.0", "bcrypt": "^5.1.1", @@ -2078,14 +2078,6 @@ "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==" }, - "node_modules/@msgpack/msgpack": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-2.8.0.tgz", - "integrity": "sha512-h9u4u/jiIRKbq25PM+zymTyW6bhTzELvOoUd+AvYriWOAKpLGnIamaET3pnHYoI5iYphAHBI4ayx0MehR+VVPQ==", - "engines": { - "node": ">= 10" - } - }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.2.tgz", @@ -5617,21 +5609,20 @@ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" }, - "node_modules/@socket.io/postgres-adapter": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@socket.io/postgres-adapter/-/postgres-adapter-0.3.1.tgz", - "integrity": "sha512-8DeSln60sFSdoLL8A8p6nrXlER4lBsvMSAS+G4sqJhudQfGOjhu2AAcKyI/SIDs4p9iO63zTbR4n//ZY0VN2bg==", + "node_modules/@socket.io/redis-adapter": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@socket.io/redis-adapter/-/redis-adapter-8.3.0.tgz", + "integrity": "sha512-ly0cra+48hDmChxmIpnESKrc94LjRL80TEmZVscuQ/WWkRP81nNj8W8cCGMqbI4L6NCuAaPRSzZF1a9GlAxxnA==", "dependencies": { - "@msgpack/msgpack": "~2.8.0", - "@types/pg": "^8.6.6", - "debug": "~4.3.4", - "pg": "^8.9.0" + "debug": "~4.3.1", + "notepack.io": "~3.0.1", + "uid2": "1.0.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=10.0.0" }, "peerDependencies": { - "socket.io-adapter": "^2.4.0" + "socket.io-adapter": "^2.5.4" } }, "node_modules/@sqltools/formatter": { @@ -12110,6 +12101,11 @@ "node": ">=0.10.0" } }, + "node_modules/notepack.io": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/notepack.io/-/notepack.io-3.0.1.tgz", + "integrity": "sha512-TKC/8zH5pXIAMVQio2TvVDTtPRX+DJPHDqjRbxogtFiByHyzKmy96RA0JtCQJ+WouyyL4A10xomQzgbUT+1jCg==" + }, "node_modules/npm-run-path": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", @@ -14906,11 +14902,32 @@ } }, "node_modules/socket.io-adapter": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", - "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", "dependencies": { - "ws": "~8.11.0" + "debug": "~4.3.4", + "ws": "~8.17.1" + } + }, + "node_modules/socket.io-adapter/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/socket.io-client": { @@ -16372,6 +16389,14 @@ "node": ">=8" } }, + "node_modules/uid2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-1.0.0.tgz", + "integrity": "sha512-+I6aJUv63YAcY9n4mQreLUt0d4lvwkkopDNmpomkAUz0fAkEMV9pRWxN0EjhW1YfRhcuyHg2v3mwddCDW1+LFQ==", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -18254,11 +18279,6 @@ "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==" }, - "@msgpack/msgpack": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-2.8.0.tgz", - "integrity": "sha512-h9u4u/jiIRKbq25PM+zymTyW6bhTzELvOoUd+AvYriWOAKpLGnIamaET3pnHYoI5iYphAHBI4ayx0MehR+VVPQ==" - }, "@msgpackr-extract/msgpackr-extract-darwin-arm64": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.2.tgz", @@ -20397,15 +20417,14 @@ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" }, - "@socket.io/postgres-adapter": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@socket.io/postgres-adapter/-/postgres-adapter-0.3.1.tgz", - "integrity": "sha512-8DeSln60sFSdoLL8A8p6nrXlER4lBsvMSAS+G4sqJhudQfGOjhu2AAcKyI/SIDs4p9iO63zTbR4n//ZY0VN2bg==", + "@socket.io/redis-adapter": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@socket.io/redis-adapter/-/redis-adapter-8.3.0.tgz", + "integrity": "sha512-ly0cra+48hDmChxmIpnESKrc94LjRL80TEmZVscuQ/WWkRP81nNj8W8cCGMqbI4L6NCuAaPRSzZF1a9GlAxxnA==", "requires": { - "@msgpack/msgpack": "~2.8.0", - "@types/pg": "^8.6.6", - "debug": "~4.3.4", - "pg": "^8.9.0" + "debug": "~4.3.1", + "notepack.io": "~3.0.1", + "uid2": "1.0.0" } }, "@sqltools/formatter": { @@ -25227,6 +25246,11 @@ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" }, + "notepack.io": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/notepack.io/-/notepack.io-3.0.1.tgz", + "integrity": "sha512-TKC/8zH5pXIAMVQio2TvVDTtPRX+DJPHDqjRbxogtFiByHyzKmy96RA0JtCQJ+WouyyL4A10xomQzgbUT+1jCg==" + }, "npm-run-path": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", @@ -27072,11 +27096,20 @@ } }, "socket.io-adapter": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", - "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", "requires": { - "ws": "~8.11.0" + "debug": "~4.3.4", + "ws": "~8.17.1" + }, + "dependencies": { + "ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "requires": {} + } } }, "socket.io-client": { @@ -28093,6 +28126,11 @@ "@lukeed/csprng": "^1.0.0" } }, + "uid2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-1.0.0.tgz", + "integrity": "sha512-+I6aJUv63YAcY9n4mQreLUt0d4lvwkkopDNmpomkAUz0fAkEMV9pRWxN0EjhW1YfRhcuyHg2v3mwddCDW1+LFQ==" + }, "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", diff --git a/server/package.json b/server/package.json index fe0fdeea69..2111413c29 100644 --- a/server/package.json +++ b/server/package.json @@ -51,7 +51,7 @@ "@opentelemetry/exporter-prometheus": "^0.52.0", "@opentelemetry/sdk-node": "^0.52.0", "@react-email/components": "^0.0.19", - "@socket.io/postgres-adapter": "^0.3.1", + "@socket.io/redis-adapter": "^8.3.0", "archiver": "^7.0.0", "async-lock": "^1.4.0", "bcrypt": "^5.1.1", diff --git a/server/src/config.ts b/server/src/config.ts index ea4ebf9d50..b2025881bb 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -384,7 +384,7 @@ export const immichAppConfig: ConfigModuleOptions = { }), }; -function parseRedisConfig(): RedisOptions { +export function parseRedisConfig(): RedisOptions { const redisUrl = process.env.REDIS_URL; if (redisUrl && redisUrl.startsWith('ioredis://')) { try { diff --git a/server/src/middleware/websocket.adapter.ts b/server/src/middleware/websocket.adapter.ts index 7b97b9f429..4978b16102 100644 --- a/server/src/middleware/websocket.adapter.ts +++ b/server/src/middleware/websocket.adapter.ts @@ -1,9 +1,9 @@ import { INestApplicationContext } from '@nestjs/common'; import { IoAdapter } from '@nestjs/platform-socket.io'; -import { createAdapter } from '@socket.io/postgres-adapter'; +import { createAdapter } from '@socket.io/redis-adapter'; +import { Redis } from 'ioredis'; import { ServerOptions } from 'socket.io'; -import { DataSource } from 'typeorm'; -import { PostgresDriver } from 'typeorm/driver/postgres/PostgresDriver.js'; +import { parseRedisConfig } from 'src/config'; export class WebSocketAdapter extends IoAdapter { constructor(private app: INestApplicationContext) { @@ -12,8 +12,9 @@ export class WebSocketAdapter extends IoAdapter { createIOServer(port: number, options?: ServerOptions): any { const server = super.createIOServer(port, options); - const pool = (this.app.get(DataSource).driver as PostgresDriver).master; - server.adapter(createAdapter(pool)); + const pubClient = new Redis(parseRedisConfig()); + const subClient = pubClient.duplicate(); + server.adapter(createAdapter(pubClient, subClient)); return server; } }