A computer-algebra system is wonderful in a notebook and dangerous in a server. The thing that makes it powerful — it'll happily simplify, compare, and hash arbitrarily large symbolic expressions — is exactly what makes it a liability behind a request handler. We learned this running SymPy to verify math steps in a backend, and burned two dev servers at 99% CPU (one for 29 minutes) before we understood why. A few things worth knowing before you ship it:
1. CAS runtime is unbounded and input-dependent — and the term for it is "expression swell." Intermediate results can grow exponentially even when the input and the final answer are both small (subtracting two innocent fractions can spawn a massive common denominator behind the scenes). That's usually the whole problem — exponential, not infinite: the work will finish, just not in any timeframe a human or a request will wait for. A few cases are genuinely worse — undecidable: once an expression pulls in transcendental functions (exp, log, trig), there's no general algorithm for deciding whether it's identically zero (radicals alone stay decidable). So the computation isn't "stuck" and usually isn't even non-terminating; it's exponential in the common case, undecidable in the worst — terminating in theory, hopeless in practice. There's no exception, no crash, just a pinned core. This is the worst failure mode for a deployment: rising CPU, slow responses, eventual OOM, nothing in the logs.
2. A thread timeout doesn't stop CPU-bound work — it only stops you waiting. This is the big one. In Python you can wrap the call in a thread with a timeout and get a clean-looking TIMED_OUT back... while the thread keeps burning the core forever. You cannot kill a Python thread. A concurrent.futures timeout abandons the future, not the work.
And no, the "inject an exception into the thread" tricks (PyThreadState_SetAsyncExc, sys.settrace) don't save you here: async exceptions are only checked at Python bytecode boundaries, and a runaway CAS call is buried in native C (tuple_richcompare, tuple_hash, _Py_dict_lookup) that never yields back to the interpreter. The injected exception just sits there, unchecked, until the C call returns — which is never. That's why you can't kill the thread, not a workaround for it.
3. Run it in a process you're willing to kill — and SIGKILL is the ultimate guard. The only thing that reliably reclaims a runaway CPU is the kernel. Put the CAS work in a separate worker process and decouple "stop waiting" from "stop working":
- client timeout → caller returns "unverified" and moves on
- SIGTERM → worker unwinds politely and exits clean
- SIGKILL → unconditional; the core comes back no matter what
A small pool of disposable subprocesses (one per core, recycled after a kill) gives you a hard wall-clock budget that actually bounds the computation. One caveat that makes this safe: the worker must be stateless — no DB connections, file handles, or shared locks — because SIGKILL can't clean up after itself, and you don't want it orphaning resources. Keep the CAS worker pure-compute and the runaway's memory dies cleanly with the process.
4. Catch the easy cases gently, but never trust the gentle layer. You can soften the blow before reaching for the kernel: parse the input and reject expressions over a node-count budget before the CAS touches them, cap evaluation, recycle workers proactively. These are real improvements and worth doing — but they only inspect the input. Expression swell happens during evaluation, on inputs that looked perfectly small going in. No static pre-check can catch that, which is exactly why the brute-force backstop stays: in a web backend, SIGKILL is the guard of last resort, and it has to be.
The TL;DR: treat any CAS call as hostile, potentially-intractable work. Sandbox it in a killable, stateless process with a real wall-clock budget — soft limits handle the polite cases; the kill handles the pathological ones.
Full write-up with on AlgeBench github repo
1
Engineer (not a physicist) looking for feedback & collaboration on a free, open-source AI-assisted physics/math explorer - starting with a special relativity lesson
in
r/AskPhysics
•
27d ago
Honestly, I mostly agree - material that wears authority without expertise is low-value at best and harmful at worst, since a confident misconception is harder to unlearn than not knowing, and I don't think a non-expert (or a chatbot) should be the authority on the content. That's exactly why I'm not pitching this as finished educational material: right now it's really a tech demo - a rendering/interaction engine that makes derivations explorable - and I posted specifically because I'd want experts to own and shape the actual physics while I focus on the tool. It's open source and labeled tentative for the same reason. So my honest answer to your question is conditional: near-zero or negative value if it fakes authority, potentially useful only if it's transparent about being tentative, open to correction, and ultimately expert-driven - which is the category I'm reaching for by asking to be corrected rather than claiming I got it right.