pi-mono/packages/chord/test/examples/36-plugin-failures/plugins/cache/server.ts
Mario Zechner a5d209afd0 feat(chord): reload restarts every affected object; old work finishes on old code
The pure swap is gone: a reload restarts every live object of a changed plugin
(documents and tables kept). Calls running at the commit and every call they cause
(the ctx call chain; an old flag on call from trusted links) run on the open old
attempt, which seals once its work drained and its successor's recorded requests are
ready, bounded by reloadDrainTimeout (5 s); then the successor's factory runs. New work
waits at the gate; same-host consumers see the draining object live; a reload cycle
fails at once with unavailable/reload_cycle. Example 64, design section 21 rewritten.
2026-11-05 18:07:11 +00:00

27 lines
1 KiB
TypeScript

// The cache plugin's server facet: `Cache` opens a store per generation, which takes a while (a native); `Status` reads
// the cache of the plugin's generation. A reload to a new generation restarts `Status`; its new code needs a new
// `Cache` object, and its old attempt stays open until that one is open.
import { constant, defineFacet, local, str } from "@earendil-works/chord";
const generation = "v1";
const Cache = local("example.cache", { version: 1, params: { generation: str() }, members: { generation: str() } });
const Status = local("example.status", { version: 1, params: {}, members: { text: str() } });
export default defineFacet((host) => {
host.serve(Cache, (params, self) => {
self.open(
async () => {
await new Promise((resolve) => setTimeout(resolve, 200));
return {};
},
() => {},
);
return { generation: constant(params.generation) };
});
host.serve(Status, (_params, self) => {
const cache = self.get(Cache, { generation });
return { text: self.derive([cache.generation], ([value]) => `cache ${value}`) };
});
});