@hocuspocus/extension-redis
Advanced tools
Comparing version 2.13.6 to 2.13.7
@@ -25,2 +25,8 @@ import RedisClient from 'ioredis'; | ||
/** | ||
* When we have a high frequency of updates to a document we don't need tons of setTimeouts | ||
* piling up, so we'll track them to keep it to the most recent per document. | ||
*/ | ||
this.pendingDisconnects = new Map(); | ||
this.pendingAfterStoreDocumentResolves = new Map(); | ||
/** | ||
* Handle incoming messages published on subscribed document channels. | ||
@@ -53,4 +59,10 @@ * Note that this will also include messages from ourselves as it is not possible | ||
this.onDisconnect = async ({ documentName }) => { | ||
const pending = this.pendingDisconnects.get(documentName); | ||
if (pending) { | ||
clearTimeout(pending); | ||
this.pendingDisconnects.delete(documentName); | ||
} | ||
const disconnect = () => { | ||
const document = this.instance.documents.get(documentName); | ||
this.pendingDisconnects.delete(documentName); | ||
// Do nothing, when other users are still connected to the document. | ||
@@ -69,3 +81,4 @@ if (!document || document.getConnectionsCount() > 0) { | ||
// Delay the disconnect procedure to allow last minute syncs to happen | ||
setTimeout(disconnect, this.configuration.disconnectDelay); | ||
const timeout = setTimeout(disconnect, this.configuration.disconnectDelay); | ||
this.pendingDisconnects.set(documentName, timeout); | ||
}; | ||
@@ -197,5 +210,18 @@ this.configuration = { | ||
if (socketId === 'server') { | ||
await new Promise(resolve => { | ||
setTimeout(() => resolve(''), this.configuration.disconnectDelay); | ||
const pending = this.pendingAfterStoreDocumentResolves.get(documentName); | ||
if (pending) { | ||
clearTimeout(pending.timeout); | ||
pending.resolve(); | ||
this.pendingAfterStoreDocumentResolves.delete(documentName); | ||
} | ||
let resolveFunction = () => { }; | ||
const delayedPromise = new Promise(resolve => { | ||
resolveFunction = resolve; | ||
}); | ||
const timeout = setTimeout(() => { | ||
this.pendingAfterStoreDocumentResolves.delete(documentName); | ||
resolveFunction(); | ||
}, this.configuration.disconnectDelay); | ||
this.pendingAfterStoreDocumentResolves.set(documentName, { timeout, resolve: resolveFunction }); | ||
await delayedPromise; | ||
} | ||
@@ -202,0 +228,0 @@ } |
@@ -68,2 +68,8 @@ /// <reference types="node" /> | ||
messagePrefix: Buffer; | ||
/** | ||
* When we have a high frequency of updates to a document we don't need tons of setTimeouts | ||
* piling up, so we'll track them to keep it to the most recent per document. | ||
*/ | ||
private pendingDisconnects; | ||
private pendingAfterStoreDocumentResolves; | ||
constructor(configuration: Partial<Configuration>); | ||
@@ -70,0 +76,0 @@ onConfigure({ instance }: onConfigurePayload): Promise<void>; |
{ | ||
"name": "@hocuspocus/extension-redis", | ||
"version": "2.13.6", | ||
"version": "2.13.7", | ||
"description": "Scale Hocuspocus horizontally with Redis", | ||
@@ -36,3 +36,3 @@ "homepage": "https://hocuspocus.dev", | ||
"dependencies": { | ||
"@hocuspocus/server": "^2.13.6", | ||
"@hocuspocus/server": "^2.13.7", | ||
"ioredis": "^4.28.2", | ||
@@ -39,0 +39,0 @@ "kleur": "^4.1.4", |
@@ -103,2 +103,10 @@ import RedisClient, { ClusterNode, ClusterOptions, RedisOptions } from 'ioredis' | ||
/** | ||
* When we have a high frequency of updates to a document we don't need tons of setTimeouts | ||
* piling up, so we'll track them to keep it to the most recent per document. | ||
*/ | ||
private pendingDisconnects = new Map<string, NodeJS.Timeout>() | ||
private pendingAfterStoreDocumentResolves = new Map<string, { timeout: NodeJS.Timeout; resolve:() => void }>() | ||
public constructor(configuration: Partial<Configuration>) { | ||
@@ -264,5 +272,23 @@ this.configuration = { | ||
if (socketId === 'server') { | ||
await new Promise(resolve => { | ||
setTimeout(() => resolve(''), this.configuration.disconnectDelay) | ||
const pending = this.pendingAfterStoreDocumentResolves.get(documentName) | ||
if (pending) { | ||
clearTimeout(pending.timeout) | ||
pending.resolve() | ||
this.pendingAfterStoreDocumentResolves.delete(documentName) | ||
} | ||
let resolveFunction: () => void = () => {} | ||
const delayedPromise = new Promise<void>(resolve => { | ||
resolveFunction = resolve | ||
}) | ||
const timeout = setTimeout(() => { | ||
this.pendingAfterStoreDocumentResolves.delete(documentName) | ||
resolveFunction() | ||
}, this.configuration.disconnectDelay) | ||
this.pendingAfterStoreDocumentResolves.set(documentName, { timeout, resolve: resolveFunction }) | ||
await delayedPromise | ||
} | ||
@@ -337,5 +363,14 @@ } | ||
public onDisconnect = async ({ documentName }: onDisconnectPayload) => { | ||
const pending = this.pendingDisconnects.get(documentName) | ||
if (pending) { | ||
clearTimeout(pending) | ||
this.pendingDisconnects.delete(documentName) | ||
} | ||
const disconnect = () => { | ||
const document = this.instance.documents.get(documentName) | ||
this.pendingDisconnects.delete(documentName) | ||
// Do nothing, when other users are still connected to the document. | ||
@@ -356,3 +391,4 @@ if (!document || document.getConnectionsCount() > 0) { | ||
// Delay the disconnect procedure to allow last minute syncs to happen | ||
setTimeout(disconnect, this.configuration.disconnectDelay) | ||
const timeout = setTimeout(disconnect, this.configuration.disconnectDelay) | ||
this.pendingDisconnects.set(documentName, timeout) | ||
} | ||
@@ -359,0 +395,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
147352
2764
Updated@hocuspocus/server@^2.13.7