Compare commits
1 Commits
feat/251-i
...
fix/252-e2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8274720281 |
@@ -33,6 +33,11 @@ export class CollaborationGateway {
|
||||
// @ts-ignore
|
||||
private readonly redisSync: RedisSyncExtension<CollabEventHandlers> | null =
|
||||
null;
|
||||
// Source ioredis client that RedisSyncExtension duplicates into its pub/sub
|
||||
// pair. The extension's onDestroy only disconnects those duplicates, so we
|
||||
// keep a reference here and disconnect the source ourselves on shutdown
|
||||
// (otherwise the socket leaks and jest never exits in e2e).
|
||||
private redisClient: RedisClient | null = null;
|
||||
private readonly withRedis: boolean;
|
||||
|
||||
constructor(
|
||||
@@ -57,16 +62,17 @@ export class CollaborationGateway {
|
||||
});
|
||||
|
||||
if (this.withRedis) {
|
||||
this.redisClient = new RedisClient({
|
||||
host: this.redisConfig.host,
|
||||
port: this.redisConfig.port,
|
||||
password: this.redisConfig.password,
|
||||
db: this.redisConfig.db,
|
||||
family: this.redisConfig.family,
|
||||
retryStrategy: createRetryStrategy(),
|
||||
});
|
||||
// @ts-ignore
|
||||
this.redisSync = new RedisSyncExtension({
|
||||
redis: new RedisClient({
|
||||
host: this.redisConfig.host,
|
||||
port: this.redisConfig.port,
|
||||
password: this.redisConfig.password,
|
||||
db: this.redisConfig.db,
|
||||
family: this.redisConfig.family,
|
||||
retryStrategy: createRetryStrategy(),
|
||||
}),
|
||||
redis: this.redisClient,
|
||||
serverId: `collab-${os?.hostname()}-${nanoid(10)}`,
|
||||
prefix: 'collab',
|
||||
pack,
|
||||
@@ -184,5 +190,10 @@ export class CollaborationGateway {
|
||||
});
|
||||
|
||||
await this.hocuspocus.hooks('onDestroy', { instance: this.hocuspocus });
|
||||
|
||||
// RedisSyncExtension.onDestroy (run via the hook above) disconnects only the
|
||||
// duplicated pub/sub clients; the source client created here is ours to close.
|
||||
this.redisClient?.disconnect();
|
||||
this.redisClient = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
PAGE_TEMPLATE_THROTTLER,
|
||||
PUBLIC_SHARE_AI_THROTTLER,
|
||||
} from './throttler-names';
|
||||
import Redis from 'ioredis';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -32,16 +31,18 @@ import Redis from 'ioredis';
|
||||
{ name: PUBLIC_SHARE_AI_THROTTLER, ttl: 60_000, limit: 5 },
|
||||
],
|
||||
errorMessage: 'Too many requests',
|
||||
storage: new ThrottlerStorageRedisService(
|
||||
new Redis({
|
||||
host: redisConfig.host,
|
||||
port: redisConfig.port,
|
||||
password: redisConfig.password,
|
||||
db: redisConfig.db,
|
||||
family: redisConfig.family,
|
||||
keyPrefix: 'throttle:',
|
||||
}),
|
||||
),
|
||||
// Pass ioredis options (not a pre-built Redis instance) so
|
||||
// ThrottlerStorageRedisService owns the connection and disconnects it
|
||||
// in its onModuleDestroy. Passing an instance leaves disconnectRequired
|
||||
// false, so the socket would leak on shutdown (e2e jest never exits).
|
||||
storage: new ThrottlerStorageRedisService({
|
||||
host: redisConfig.host,
|
||||
port: redisConfig.port,
|
||||
password: redisConfig.password,
|
||||
db: redisConfig.db,
|
||||
family: redisConfig.family,
|
||||
keyPrefix: 'throttle:',
|
||||
}),
|
||||
};
|
||||
},
|
||||
inject: [EnvironmentService],
|
||||
|
||||
Reference in New Issue
Block a user