mirror of
https://github.com/alexandrev/xslt-lab.git
synced 2026-09-13 08:43:16 +00:00
4e1f3ffdac
The backend container runs three JVMs — Saxon 12, Saxon 9.6 and Xalan — whose -Xmx values add up to 512 MB, inside a container limited to 256Mi. The limit was half the heap the JVMs believed they had, so the kernel was killing the container: OOMKilled twice a day on the 16th and 17th of August, five times a day on the 18th and 19th, and 81 users in 24 hours got "transform service unavailable" instead of a result. Before each kill the serial collector spends hours in continuous full GC, which is why three of the five pods sat pinned at exactly 0.5 CPU — their limit — around the clock, and why XSLT 2.0's p95 was 5.5s against 0.7s for the other two engines. Those limits were never in the chart to begin with: the backend deployment has never rendered a resources block, values.resources.backend was declared and unused, and the live numbers came from a manual kubectl patch that an ArgoCD sync would have silently dropped. So the chart now owns them, with room for what actually runs in there. The CPU request moves 10m -> 250m as well: against real usage of 500m the HPA read utilisation in the thousands of percent and the deployment sat permanently at maxReplicas, unable to signal anything. And the backend gets minReplicas 2, for the reason the frontend already learnt. The other half is the mid-keystroke problem again, one level down. Gating the automatic run on well-formedness took the error rate from 54% to 24%, but a stylesheet whose XPath is half-typed is perfectly good XML, so it still went to the backend and still came back as a compile error. A day of logs is mostly that, keystroke by keystroke: 'current()/..[@N' then '[@Na' then '[@Name', and "Required attribute 'select' is missing" 65 times on a single line. So the gate now also declines to send an expression that is provably unfinished — a required attribute that is absent, an empty value, a quote or bracket still open, a trailing token that cannot end an expression. Facts about the text, not guesses at intent: there are twice as many tests for what it must leave alone as for what it catches, including every template the app itself ships. It is skipped above 64KB, where a document was pasted rather than typed, and as before it only holds back the automatic run — "Run it anyway" is always there. Finally, the error classifier learns the rest of what was sitting in "other": Xalan's "Syntax error in '<expr>'" is the stylesheet's XPath, not the input. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018HnUwBeXv6PCTEzRpFoMSU
xslt-playground Helm Chart
This chart deploys the frontend and backend of xslt-playground.
Configuration
Key parameters in values.yaml:
image.frontendandimage.backend– container images.firebase.enabled– set tofalseto disable Firebase integration entirely. When enabled you must provide a secret named byfirebase.secretNamewith the keysfirebase.credentialsKeyandfirebase.configKey. The backend mounts the credentials file atfirebase.credentialsMountPathand the frontend reads the config JSON.storage.enabled– disable database usage whenfalse. If enabled the backend getsDATABASE_URLfromstorage.databaseUrl; otherwise the environment variableDISABLE_DATABASE=trueis set.ingress– configure ingress for the frontend service. The backend is exposed through a second ingress using the hostnamebackend.<hostname>with the same settings.frontend.backendUrl– value forVITE_BACKEND_URLused by the frontend. The frontend reads this variable at runtime so changing the deployment does not require rebuilding the image. When empty it defaults to the internal backend service URL.frontend.googleAnalyticsId– setsVITE_GA_IDto enable Google Analytics.adsTxt– optional content for anads.txtfile served by the frontend pod.hpa– enable CPU-based autoscaling for both deployments.
When firebase.enabled is true you must create the secret before installing the chart:
kubectl create secret generic firebase-config \
--from-file=service-account.json=</path/to/serviceAccount.json> \
--from-file=firebase-config.json=</path/to/firebaseConfig.json>
Install the chart with:
helm install xslt charts/xslt-playground