diff options
| author | eunhhu <[email protected]> | 2026-09-25 15:49:48 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-09-25 15:49:48 +0100 |
| commit | 18675f3e45fa0896efd777bf66ad0ec4c8157d36 (patch) | |
| tree | 058a22fc929e974cef70cc1ddbd5dc54f56bf55c /prototypes/connections/pure-run.c | |
| parent | 49c29a1255e1ad3f7fde6c64910c7d2c38edad78 (diff) | |
| download | pure-18675f3e45fa0896efd777bf66ad0ec4c8157d36.tar.gz pure-18675f3e45fa0896efd777bf66ad0ec4c8157d36.zip | |
Keep app states in the tree store
When the data host keeps states (PureData.state and .save, implemented by
pure_tree_data), every state of an app lives in the store: a text state's
draft is its stored value, a list mirrors each change into a stored draft
(record header, then items), and numbers, cursors and indices are stored
together by name. An app starts from what is stored, moves list fields by
name when a record changed, resets cursors and indices that no longer fit,
and refuses damaged stored values.
Each key, text and message event publishes the states it changed together
with the message's document in one store commit, or fails and leaves
memory and store as they were. Frame changes go with the next event or
pure_app_save. pure-run takes --store PATH.
Tests run the same random events on an app in memory and on a stored app
that restarts every few events and require equal states after every step;
kill a process at every commit stage of an event that changes a number, a
text and a list; and check frames, message atomicity and migration by
restart and by replacement. A stored event costs about 10.6 ms more on the
Pi's SD card, mostly two fsyncs.
Diffstat (limited to 'prototypes/connections/pure-run.c')
| -rw-r--r-- | prototypes/connections/pure-run.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/prototypes/connections/pure-run.c b/prototypes/connections/pure-run.c index 8a9788f..7b6e253 100644 --- a/prototypes/connections/pure-run.c +++ b/prototypes/connections/pure-run.c @@ -1,12 +1,15 @@ #define _POSIX_C_SOURCE 200809L -#include "module.h" +#include "module-store.h" +#include "store.h" #include <stdio.h> #include <stdlib.h> #include <string.h> /* Test host for a verified module: reads commands from stdin and prints one - * JSON snapshot per command. Not a product interface. - * down NAME | up NAME | frame [N] | type NAME HEX|- | replace PATH | show + * JSON snapshot per command. Not a product interface. With --store the app's + * states live in that tree store: it starts from them, and frame changes are + * saved at the end of input or by save. + * down NAME | up NAME | frame [N] | type NAME HEX|- | replace PATH | save | show * Text states and text views print as JSON strings; cursors as byte positions; * lists as arrays of objects; indices as positions; a table view as an array * with an object of its columns per row. A failed view or cell is null. */ @@ -131,13 +134,16 @@ static int hex(char c) { int main(int argc, char **argv) { static PureModule modules[2]; - if (argc != 2 || !load(argv[1], &modules[0])) { - if (argc != 2) fputs("pure-run MODULE < commands\n", stderr); + bool stored = argc == 4 && !strcmp(argv[2], "--store"); + if ((argc != 2 && !stored) || !load(argv[1], &modules[0])) { + if (argc != 2 && !stored) fputs("pure-run MODULE [--store PATH] < commands\n", stderr); return 2; } + if (stored && pure_store_init(argv[3]) != PURE_OK) { fprintf(stderr, "cannot open store %s\n", argv[3]); return 2; } unsigned active = 0; PureApp app; - if (pure_app_start(&app, &modules[active], (PureData){0}) != PURE_OK) { fputs("cannot start\n", stderr); return 2; } + PureResult started = pure_app_start(&app, &modules[active], stored ? pure_tree_data(argv[3]) : (PureData){0}); + if (started != PURE_OK) { fprintf(stderr, "cannot start (%d)\n", (int)started); return 2; } static char line[1 << 16]; static unsigned char text[1 << 15]; int status = 0; @@ -167,10 +173,13 @@ int main(int argc, char **argv) { if (!load(argument, &modules[!active])) failure = "invalid module"; else if (pure_app_replace(&app, &modules[!active]) != PURE_OK) failure = "replace failed"; else active = !active; + } else if (!strcmp(command, "save")) { + if (pure_app_save(&app) != PURE_OK) failure = "save failed"; } else if (strcmp(command, "show")) failure = "unknown command"; if (failure) status = 1; show(&app, failure); } + if (pure_app_save(&app) != PURE_OK) { fputs("cannot save\n", stderr); status = 1; } pure_app_stop(&app); return status; } |
