@@ -16,6 +16,7 @@ import {
1616 type onStoreDocumentPayload
1717} from '@hocuspocus/server'
1818import { type ExecutionResult , type Lock , Redlock } from '@sesamecare-oss/redlock'
19+ import tracer , { Span } from 'dd-trace'
1920import RedisClient , {
2021 type Cluster ,
2122 type ClusterNode ,
@@ -101,6 +102,7 @@ export class Redis implements Extension {
101102 redlock : Redlock
102103
103104 locks = new Map < string , { lock : Lock ; release ?: Promise < ExecutionResult > } > ( )
105+ spans = new Map < string , Span > ( )
104106
105107 messagePrefix : Buffer
106108
@@ -235,12 +237,21 @@ export class Redis implements Extension {
235237 // to avoid conflict with other instances storing the same document.
236238 const resource = this . lockKey ( documentName )
237239 const ttl = this . configuration . lockTimeout
238- const lock = await this . redlock . acquire ( [ resource ] , ttl )
239- const oldLock = this . locks . get ( resource )
240- if ( oldLock ) {
241- await oldLock . release
240+
241+ const span = tracer . startSpan ( 'hocusPocusRedis.onStoreDocument' , { tags : { resource} } )
242+ try {
243+ const lock = await this . redlock . acquire ( [ resource ] , ttl )
244+ const oldLock = this . locks . get ( resource )
245+ if ( oldLock ) {
246+ await oldLock . release
247+ }
248+ this . locks . set ( resource , { lock} )
249+ this . spans . set ( resource , span )
250+ } catch ( error ) {
251+ span . setTag ( 'error' , error )
252+ span . finish ( )
253+ throw error
242254 }
243- this . locks . set ( resource , { lock} )
244255 }
245256
246257 /**
@@ -249,8 +260,15 @@ export class Redis implements Extension {
249260 async afterStoreDocument ( { documentName, socketId} : afterStoreDocumentPayload ) : Promise < void > {
250261 const lockKey = this . lockKey ( documentName )
251262 const lock = this . locks . get ( lockKey )
263+ const span = this . spans . get ( lockKey )
252264 if ( ! lock ) {
253- throw new Error ( `Lock created in onStoreDocument not found in afterStoreDocument: ${ lockKey } ` )
265+ const error = new Error (
266+ `Lock created in onStoreDocument not found in afterStoreDocument: ${ lockKey } `
267+ )
268+ span ?. setTag ( 'error' , error )
269+ span ?. finish ( )
270+ this . spans . delete ( lockKey )
271+ throw error
254272 }
255273 try {
256274 // Always try to unlock and clean up the lock
@@ -259,7 +277,9 @@ export class Redis implements Extension {
259277 } catch {
260278 // Lock will expire on its own after timeout
261279 } finally {
280+ span ?. finish ( )
262281 this . locks . delete ( lockKey )
282+ this . spans . delete ( lockKey )
263283 }
264284 if ( socketId !== 'server' ) return
265285 // if the change was initiated by a directConnection, we need to delay this hook to make sure sync can finish first.
0 commit comments