the published fragment. -->
cordispy · interactive model of examples/run_benefit.py
One application, built twice — on the cordis runtime and on a conventional plugin registry. Step through the walkthrough, or drive them yourself, and watch where they stop agreeing.
The lab
The component under test is tool_kv. It mounts routes and opens a journal connection
when it loads — and it opens a sqlite connection per key shard, arms a compaction timer and
subscribes a tracer while serving a request, long after setup() returned.
That last part is the whole experiment.
Reach the state that --scenario residue measures to check the model against the real run.
Drive the two runtimes yourself. The walkthrough above never touches these controls, so anything you change here is your own experiment - press Restart to put the walkthrough back in charge.
Why it diverges
Effects
An effect is a pair — acquire this, and here is how to give it back — recorded on the fiber rather than on the call that ran it. An effect created inside a request handler lands on the same accumulator as one created at load time, so unloading reverses both. Recovery is last-applied-first and happens at most once.
The registry’s teardown() is a method whose author knew only what
setup() did. It pops the two routes it mounted and closes the journal it opened.
It cannot know about the /kv index route the mount helper added on its behalf, and
it certainly cannot know about a connection opened by a request that had not happened yet.
Coeffects
tool_kv reads ctx.store once and holds it for its whole life. In a
conventional system that cached reference is a bug waiting for the provider to be replaced.
Here it is correct, because replacing the provider changes the fiber’s target, which
unloads the component and loads it again — with a fresh read.
That is also why a component the runtime can activate is one it can deactivate. Set the provider to none and watch one side go quiet and give everything back, while the other keeps reporting itself registered and healthy right up until the next request.
Run it for real
The walkthrough above is modelled on tests/UAT/benefit.sh, which runs the same
sequence against the real runtime and asserts each step. There the counts come from a live
process: pending tasks are asyncio.all_tasks() set differences, a connection counts
as open only if it still answers select 1, and routes and subscribers are read off
the actual dispatcher and bus.
cordispy is a Python realization of the runtime described in A Programming Paradigm for
Spatiotemporal Composability (Shi, Zhang, Cui). The conventional side is a faithful
implementation of the design most plugin systems converge on — no missing cleanup call and no
planted bug; its teardown() undoes exactly what its setup() did. See
examples/naive/, docs/benefits.md, and tests/UAT/.