From 517d5cf263bdbea232186636ce99e7c3be15d00f Mon Sep 17 00:00:00 2001 From: eunhhu Date: Fri, 25 Sep 2026 16:06:21 +0100 Subject: Save app changes in bursts A save now publishes everything since the last save in one commit: the documents messages edited and the states that changed. If it fails, every event since the last save is undone (values, text and list drafts, the list undo log, event and tick counts), so an event reported as successful is stored and a failed one leaves no trace. By default each key, text and message event saves before it returns, as before. With pure_app_defer events apply at once and a host saves a burst with one commit; a key's document joins a burst once, so revisions move one per save. On the Pi's SD card 600 events take 6.3 s saved one by one, 0.97 s in bursts of 8 and 0.34 s in bursts of 64. pure-run takes --batch N. Tests compare a deferred stored app that saves at random and sometimes stops unsaved with an app that replays only the saved events, undo a whole burst on a failed save, and kill a process while it saves a burst. --- prototypes/connections/module-store.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'prototypes/connections/module-store.c') diff --git a/prototypes/connections/module-store.c b/prototypes/connections/module-store.c index 6335903..02d6361 100644 --- a/prototypes/connections/module-store.c +++ b/prototypes/connections/module-store.c @@ -42,17 +42,19 @@ static PureResult state(void *context, const char *name, PureDraft **out) { return pure_state_open(context, name, out); } -/* The document and the app's changed states in one tree commit. */ -static PureResult save(void *context, void *document, PureDraft *const *states, size_t count, int64_t *revision) { +enum { SAVED = PURE_APP_PENDING + 2 * PURE_MODULE_STATES + 1 }; + +/* The documents and the app's changed states in one tree commit. */ +static PureResult save(void *context, void *const *documents, size_t document_count, PureDraft *const *states, + size_t count, int64_t *revisions) { (void)context; - PureDraft *drafts[2 * PURE_MODULE_STATES + 2] = {0}; - int64_t revisions[2 * PURE_MODULE_STATES + 2] = {0}; - size_t n = 0; - if (count > 2 * PURE_MODULE_STATES + 1) return PURE_LIMIT; - if (document) drafts[n++] = document; - for (size_t i = 0; i < count; ++i) drafts[n++] = states[i]; - PureResult result = pure_draft_commit_all(drafts, n, revisions); - if (document) *revision = revisions[0]; + PureDraft *drafts[SAVED] = {0}; + int64_t all[SAVED] = {0}; + if (document_count > PURE_APP_PENDING || count > SAVED - document_count) return PURE_LIMIT; + for (size_t i = 0; i < document_count; ++i) drafts[i] = documents[i]; + for (size_t i = 0; i < count; ++i) drafts[document_count + i] = states[i]; + PureResult result = pure_draft_commit_all(drafts, document_count + count, all); + for (size_t i = 0; i < document_count; ++i) revisions[i] = all[i]; return result; } -- cgit v1.2.3