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.
The build job now needs: test, so an image cannot be published with the suite in
red — which is the whole point of this phase. Both jobs live in the same file
because needs: only links jobs within one workflow.
settings-ci.json is committed and contains no secrets: settings-development.json
is gitignored, so CI had nothing to pass to --settings. The one test that cannot
work without a secret is the node-red iron fixture, sealed with the deployment's
own ironPassword; it now reports itself as skipped instead of failing on an hmac
mismatch, and still runs locally against settings-development.json.
Measured locally: 22s and a ~2.0 GB peak for the whole `meteor test` run (its own
mongod included), hence --memory=3g. The meteor-tool download is not cached yet;
the note in the workflow says what that would take.
activefiresmyloc (bounding box, published fields, out-of-range coordinates),
activefiresunionmyloc (geoIntersects, including a shape larger than the viewport)
and mysubscriptions (own subscriptions only, nothing for anonymous visitors).
Runs the real worker against the real @turf modules, because what broke twice was
never the geometry: the worker script and the turf packages sit in sibling
directories of the bundle that a bare require() cannot reach (3249362), and the
first fix doubled the programs/server prefix so nothing resolved (570cb49).
The last test is the reason the worker exists at all: timers keep firing while a
120-circle union computes. Revert fbb746f and it fails.
The cases are the incidents: a worker failure must leave the stored union alone
instead of overwriting it with "null" (50ca9cc), an incremental merge must refuse
to run on state that is not exactly one behind, recomputes must coalesce while
adds must not be dropped, and legacy telegram subscriptions (no radius, no
location) must be skipped without throwing.
Also the 16 MiB case the FIXME asked for: a 20 MB union comes back under the cap,
still parseable, with the degradation recorded.