Skip to content

Cut provisioning round-trips: merge working+drafts, add PriorHash cac…#73

Merged
attermann merged 1 commit into
masterfrom
mgmt_optimizations
Jul 20, 2026
Merged

Cut provisioning round-trips: merge working+drafts, add PriorHash cac…#73
attermann merged 1 commit into
masterfrom
mgmt_optimizations

Conversation

@attermann

Copy link
Copy Markdown
Owner

…he, embed post-op state

Every provisioning transaction over LoRa pays fixed framing + encryption

  • Link overhead that dominates the actual payload. The webconsole previously needed 2-3 transactions per user action: Save = SetState + GetState refresh; Commit = Commit + GetInfo + GetState refresh; PanelOpen = GetState[working] + GetState[drafts] with a client-side diff to figure out which fields were drafted. This rework collapses each flow to a single transaction plus a cache-hit short-circuit for unchanged state.
  • GET_CAPABILITIES returns a namespace map with per-ns schema hashes (was a bare id array); GET_SCHEMA gains NamespaceFilter. Enables lazy per-namespace schema loading with content-addressed caching.
  • GET_STATE gains Draft (merge drafts into the working response), PriorHash (server responds { Unchanged: true } on cache hit), and Hash. Body is now { Values, Drafts?, Hash } instead of the raw ns->fields map.
  • SET_STATE wraps the state map in { State, IncludeState? }; with IncludeState the response carries PostOpValues + PostOpDrafts + PostOpHash so Save refreshes in one round-trip.
  • COMMIT uses a { NamespaceFilter?, IncludeState? } map (was a bare array); with IncludeState the response carries PostOpValues + PostOpHash so Commit refreshes in one round-trip.

Two latent bugs addressed: the "phantom draft from live-metric drift" that the old double-fetch pattern had to work around client-side (current_rssi and friends sampled differently between the two calls), and a Key-namespace collision (Applied=1 vs Values=1) that would have produced duplicate-key maps in the new commit response — fixed by giving post-op state distinct slots (PostOpValues=4, PostOpDrafts=5, PostOpHash=6).

Extract pack_ns_values / pack_ns_drafts helpers so op_get_state, op_set_state, and op_commit emit byte-identical Values/Drafts sub-maps — that lets SetState's PostOpHash prime the GetState PriorHash cache.

71/71 provisioning tests pass. Docs: rewrite provisioning_client_guide.md for the new wire; update provisioning_integration_guide.md (SCHEMA_VERSION=2, Void field type, schema_hash accessor); CHANGELOG gains an entry per new mechanism plus migration notes for the wire- format breaks.

…he, embed post-op state

Every provisioning transaction over LoRa pays fixed framing + encryption
+ Link overhead that dominates the actual payload. The webconsole
previously needed 2-3 transactions per user action:
Save = SetState + GetState refresh; Commit = Commit + GetInfo + GetState
refresh; PanelOpen = GetState[working] + GetState[drafts] with a
client-side diff to figure out which fields were drafted. This rework
collapses each flow to a single transaction plus a cache-hit
short-circuit for unchanged state.

- GET_CAPABILITIES returns a namespace map with per-ns schema hashes
  (was a bare id array); GET_SCHEMA gains NamespaceFilter. Enables
  lazy per-namespace schema loading with content-addressed caching.
- GET_STATE gains Draft (merge drafts into the working response),
  PriorHash (server responds { Unchanged: true } on cache hit), and
  Hash. Body is now { Values, Drafts?, Hash } instead of the raw
  ns->fields map.
- SET_STATE wraps the state map in { State, IncludeState? }; with
  IncludeState the response carries PostOpValues + PostOpDrafts +
  PostOpHash so Save refreshes in one round-trip.
- COMMIT uses a { NamespaceFilter?, IncludeState? } map (was a bare
  array); with IncludeState the response carries PostOpValues +
  PostOpHash so Commit refreshes in one round-trip.

Two latent bugs addressed: the "phantom draft from live-metric drift"
that the old double-fetch pattern had to work around client-side
(current_rssi and friends sampled differently between the two calls),
and a Key-namespace collision (Applied=1 vs Values=1) that would have
produced duplicate-key maps in the new commit response — fixed by
giving post-op state distinct slots (PostOpValues=4, PostOpDrafts=5,
PostOpHash=6).

Extract pack_ns_values / pack_ns_drafts helpers so op_get_state,
op_set_state, and op_commit emit byte-identical Values/Drafts sub-maps
— that lets SetState's PostOpHash prime the GetState PriorHash cache.

71/71 provisioning tests pass. Docs: rewrite provisioning_client_guide.md
for the new wire; update provisioning_integration_guide.md
(SCHEMA_VERSION=2, Void field type, schema_hash accessor); CHANGELOG
gains an entry per new mechanism plus migration notes for the wire-
format breaks.
@attermann
attermann merged commit c8f018f into master Jul 20, 2026
8 checks passed
@attermann
attermann deleted the mgmt_optimizations branch July 20, 2026 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant