@@ -5,11 +5,12 @@ import type {
55 Hocuspocus ,
66 afterLoadDocumentPayload ,
77 afterStoreDocumentPayload ,
8+ afterUnloadDocumentPayload ,
89 beforeBroadcastStatelessPayload ,
10+ beforeUnloadDocumentPayload ,
911 onAwarenessUpdatePayload ,
1012 onChangePayload ,
1113 onConfigurePayload ,
12- onDisconnectPayload ,
1314 onStoreDocumentPayload ,
1415} from "@hocuspocus/server" ;
1516import {
@@ -108,12 +109,6 @@ export class Redis implements Extension {
108109
109110 messagePrefix : Buffer ;
110111
111- /**
112- * When we have a high frequency of updates to a document we don't need tons of setTimeouts
113- * piling up, so we'll track them to keep it to the most recent per document.
114- */
115- private pendingDisconnects = new Map < string , NodeJS . Timeout > ( ) ;
116-
117112 private pendingAfterStoreDocumentResolves = new Map <
118113 string ,
119114 { timeout : NodeJS . Timeout ; resolve : ( ) => void }
@@ -389,42 +384,25 @@ export class Redis implements Extension {
389384 }
390385
391386 /**
392- * Make sure to *not* listen for further changes, when there’s
393- * no one connected anymore.
387+ * Delay unloading to allow syncs to finish
394388 */
395- public onDisconnect = async ( { documentName } : onDisconnectPayload ) => {
396- const pending = this . pendingDisconnects . get ( documentName ) ;
397-
398- if ( pending ) {
399- clearTimeout ( pending ) ;
400- this . pendingDisconnects . delete ( documentName ) ;
401- }
402-
403- const disconnect = ( ) => {
404- const document = this . instance . documents . get ( documentName ) ;
405-
406- this . pendingDisconnects . delete ( documentName ) ;
407-
408- // Do nothing, when other users are still connected to the document.
409- if ( document && document . getConnectionsCount ( ) > 0 ) {
410- return ;
411- }
389+ async beforeUnloadDocument ( data : beforeUnloadDocumentPayload ) {
390+ return new Promise < void > ( ( resolve ) => {
391+ setTimeout ( ( ) => {
392+ resolve ( ) ;
393+ } , this . configuration . disconnectDelay ) ;
394+ } ) ;
395+ }
412396
413- // Time to end the subscription on the document channel.
414- this . sub . unsubscribe ( this . subKey ( documentName ) , ( error : any ) => {
415- if ( error ) {
416- console . error ( error ) ;
417- }
418- } ) ;
397+ async afterUnloadDocument ( data : afterUnloadDocumentPayload ) {
398+ if ( data . instance . documents . has ( data . documentName ) ) return ; // skip unsubscribe if the document is already loaded again (maybe fast reconnect)
419399
420- if ( document ) {
421- this . instance . unloadDocument ( document ) ;
400+ this . sub . unsubscribe ( this . subKey ( data . documentName ) , ( error : any ) => {
401+ if ( error ) {
402+ console . error ( error ) ;
422403 }
423- } ;
424- // Delay the disconnect procedure to allow last minute syncs to happen
425- const timeout = setTimeout ( disconnect , this . configuration . disconnectDelay ) ;
426- this . pendingDisconnects . set ( documentName , timeout ) ;
427- } ;
404+ } ) ;
405+ }
428406
429407 async beforeBroadcastStateless ( data : beforeBroadcastStatelessPayload ) {
430408 const message = new OutgoingMessage (
0 commit comments