Cuatro endurecimientos salidos del banco de carga (bench/union-bench.js), cada
uno con su número:
1. Unión en ÁRBOL en vez de en cadena. La cadena unía siempre contra un polígono
acumulado que no paraba de crecer. Con 1.000 suscripciones repartidas por el
mundo —el peor caso, círculos que no se solapan— eran 238 s; en árbol son
3,6 s, con un documento idéntico. Con datos realistas (España) 10.000
suscripciones bajan de 39,3 s a 23,5 s. test/server/calcUnionAsync.test.js
comprueba la equivalencia contra una referencia calculada en cadena.
2. 64 vértices por círculo en vez de 144, configurable con
`private.unionCircleSteps`. Con 10.000 suscripciones: 23,5 s → 10,0 s y el
pico de RSS de 777 MB → 421 MB. En pantalla un círculo de 64 lados sigue
siendo un círculo, y la capa de zonas es un adorno difuso; el host de
despliegue tiene 5,9 GB para todo el stack.
3. Timeout del worker (10 min por defecto, `private.unionWorkerTimeoutMs`). Un
worker que no contestaba dejaba la promesa colgada y con ella la cola entera:
`busy` se quedaba en true y no se volvía a calcular ninguna unión hasta
reiniciar, sin que nada fallase. Se reintenta una vez ante un error real,
nunca ante un timeout.
4. Cota de heap del worker (1 GB, `private.unionWorkerMaxHeapMb`), para que un
caso patológico muera con ERR_WORKER_OUT_OF_MEMORY —que esta capa convierte
en un rechazo, dejando la unión anterior intacta— en vez de que el kernel se
lleve por delante el proceso de Meteor.
Además unionTelemetry.js manda a GlitchTip las uniones que pasan de un minuto y
las que hay que degradar por tamaño, y registra duración/tamaño de cada una. El
único aviso de que la unión iba mal era, hasta ahora, que el mapa se quedaba
viejo.
Smoke REST byte-idéntico. 90 tests en verde.
Ejecuta el worker de producción contra suscripciones sintéticas realistas
(península, Canarias, Baleares; radios de 5 a 100 km) y mide lo que la fase 12
pide: duración del recreate completo y del incrementalAdd, retraso máximo del
event loop del proceso padre —que es donde vive DDP y por tanto la pregunta
real de "¿se congela la web?"—, tamaño del documento frente al límite de 16 MiB
y pico de RSS.
`--spread world` reparte las suscripciones por todo el mundo: es el peor caso
para el tamaño, porque casi no se solapan y la unión conserva un polígono por
suscripción en vez de fundirlos.
treeUnionWorker.js es una variante solo del banco (une en árbol en vez de en
cadena) para poder comparar estrategias con números antes de tocar el worker
de verdad. El worker de producción solo cambia en que ahora acepta `steps` por
workerData, con el mismo 144 de siempre por defecto.