diff options
| author | eunhhu <[email protected]> | 2026-09-30 05:33:32 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-09-30 05:33:32 +0100 |
| commit | 9aa123ec5e8827a6101fa7c6db139397b39e04f2 (patch) | |
| tree | 4e50377e9a9f29f39c3a1e8ef37ce629dfbe8e17 /serve | |
| parent | baaf955959d4b2187e93e35b64cd3f5b2330a59a (diff) | |
| download | pure-9aa123ec5e8827a6101fa7c6db139397b39e04f2.tar.gz pure-9aa123ec5e8827a6101fa7c6db139397b39e04f2.zip | |
Recast waiting sends by field name when an output's fields change
Review 004's F3 made a module refuse to start while sends waited on an
output whose fields it had changed: their bytes would have meant
something else. Safe, but it deadlocks a rolling upgrade. Growing a
board shared by two nodes: one upgraded to a card with a new field
refuses the other's old sends (another shape), and the other, its old
sends waiting, cannot start the new module at all ("Cannot start the
module on the store", saying nothing more).
Waiting sends now move to the new fields by name, as a list's items do:
a value goes over when the new type can hold it (u32 and number are
numbers, bytes and text are bytes; a number that is not a u32, or bytes
that are not UTF-8 for a text, cannot), the rest start at 0 or empty
(pure_send_recast, with the payload layout load uses, pure_fields_lay_out).
A start recasts them and a replace does into a new outbox.
Their meaning must survive a crash between the recast and the save that
names the new fields in the links. So the outbox's image now names the
fields its sends were laid out with ("PLO1": the module's outputs after
the save it holds), and is written again before any send is logged with
other fields; a start reads those names over the links'. Checkpoints of
the outbox name them too.
A module without an output that sends wait on is still refused, now
saying so in PureApp.why, which pure-serve prints ("sends wait on the
output 'ordered', which this module does not have"); a failed start
keeps it.
test-module send_recast (widened, narrowed, UTF-8, a payload not laid
out, there and back) and output_meaning (the swapped fields recast on a
replace, read right after a restart that never saved, back again, sends
logged after the image, the refusal and its reason). check.py
server_upgrade: five sends wait on the old output, the sender starts
with the new one, the old receiver refuses the new shape, the new one
takes all eight.
Diffstat (limited to 'serve')
| -rw-r--r-- | serve/serve.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/serve/serve.c b/serve/serve.c index a9dd9d4..d06f430 100644 --- a/serve/serve.c +++ b/serve/serve.c @@ -2230,7 +2230,7 @@ static bool start_executor(Executor *ex, const PureModule *module, uint32_t show ex->edit = edit; if (pure_store_open(store, &ex->store) != PURE_OK) { fputs("Cannot open the store\n", stderr); return false; } if (pure_app_start(&ex->app, module, pure_store_data(ex->store)) != PURE_OK || !pure_app_defer(&ex->app, true)) { - fputs("Cannot start the module on the store\n", stderr); + fprintf(stderr, "Cannot start the module on the store%s%s\n", ex->app.why[0] ? ": " : "", ex->app.why); return false; } pure_app_background_checkpoints(&ex->app, true); |
