fix: remove worker mutex and increase collab timeout to 120s #11

Merged
aleleba merged 1 commits from fix/remove-worker-mutex-increase-timeout into main 2026-06-01 14:27:23 -06:00
Owner

Problema

Al escribir páginas largas vía WebSocket, el servidor sufría timeouts por dos causas:

  1. Mutex workerBusy en src/index.ts: cada worker procesaba 1 request a la vez en cola. Si una request lenta (escritura de página grande) ocupaba el worker, la siguiente esperaba en cola y podía expirar antes de ser atendida.
  2. Timeout de 25 s en collaboration.ts: para páginas grandes, el sync inicial de Hocuspocus (Yjs) puede superar fácilmente los 25 s, causando un rechazo prematuro.

Solución

1. Eliminar el mutex (src/index.ts)

StreamableHTTPServerTransport es stateless — se crea uno por request. No hay estado compartido entre requests concurrentes dentro del mismo worker, por lo que el mutex era innecesario. Al eliminarlo, cada worker puede atender múltiples requests en paralelo sin starvation.

// Antes — serializado
workerBusy = workerBusy.then(() => handleMcpRequest(req, res)).catch(...)

// Después — concurrente
handleMcpRequest(req, res).catch(...)

2. Aumentar el timeout de colaboración (src/lib/collaboration.ts)

El timeout de seguridad sube de 25 s → 120 s, dando tiempo suficiente a documentos grandes para completar la fase de sync de Yjs antes del abort.

Impacto

  • Sin cambios en la API pública ni en el comportamiento externo.
  • El cluster de workers sigue funcionando igual (Node.js cluster comparte el puerto 8080 vía IPC del master).
  • Las conexiones background de 15 s para el debounce de Docmost no se ven afectadas.
## Problema Al escribir páginas largas vía WebSocket, el servidor sufría timeouts por dos causas: 1. **Mutex `workerBusy` en `src/index.ts`**: cada worker procesaba 1 request a la vez en cola. Si una request lenta (escritura de página grande) ocupaba el worker, la siguiente esperaba en cola y podía expirar antes de ser atendida. 2. **Timeout de 25 s en `collaboration.ts`**: para páginas grandes, el sync inicial de Hocuspocus (Yjs) puede superar fácilmente los 25 s, causando un rechazo prematuro. ## Solución ### 1. Eliminar el mutex (`src/index.ts`) `StreamableHTTPServerTransport` es stateless — se crea uno por request. No hay estado compartido entre requests concurrentes dentro del mismo worker, por lo que el mutex era innecesario. Al eliminarlo, cada worker puede atender múltiples requests en paralelo sin starvation. ```ts // Antes — serializado workerBusy = workerBusy.then(() => handleMcpRequest(req, res)).catch(...) // Después — concurrente handleMcpRequest(req, res).catch(...) ``` ### 2. Aumentar el timeout de colaboración (`src/lib/collaboration.ts`) El timeout de seguridad sube de **25 s → 120 s**, dando tiempo suficiente a documentos grandes para completar la fase de sync de Yjs antes del abort. ## Impacto - Sin cambios en la API pública ni en el comportamiento externo. - El cluster de workers sigue funcionando igual (Node.js `cluster` comparte el puerto 8080 vía IPC del master). - Las conexiones background de 15 s para el debounce de Docmost no se ven afectadas.
aleleba added 1 commit 2026-06-01 14:26:26 -06:00
- Remove workerBusy promise chain (mutex) in src/index.ts: each
  StreamableHTTPServerTransport is stateless and per-request, so
  concurrent handling within a worker is safe. Eliminates request
  starvation when long page writes are in flight.
- Raise the Hocuspocus safety timeout in collaboration.ts from 25 s
  to 120 s, giving large documents enough time to complete the Yjs
  sync phase before the hard abort fires.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
aleleba merged commit e7cf1fa022 into main 2026-06-01 14:27:23 -06:00
aleleba deleted branch fix/remove-worker-mutex-increase-timeout 2026-06-01 14:27:26 -06:00
Sign in to join this conversation.