Al escribir páginas largas vía WebSocket, el servidor sufría timeouts por dos causas:
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.
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.
- 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 main2026-06-01 14:27:23 -06:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problema
Al escribir páginas largas vía WebSocket, el servidor sufría timeouts por dos causas:
workerBusyensrc/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.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)StreamableHTTPServerTransportes 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.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
clustercomparte el puerto 8080 vía IPC del master).