diff --git a/context/adr/009-incremental-evaluation.md b/context/adr/009-incremental-evaluation.md index 0568dab0..6099ec8b 100644 --- a/context/adr/009-incremental-evaluation.md +++ b/context/adr/009-incremental-evaluation.md @@ -144,7 +144,8 @@ with the same key, from any client. The key is: - the page categories, so each page is a maintained slice and paging rebuilds nothing; - `measure_agg`. -Everything else in a request is applied when output is read: hidden and collapsed items +The key uses the canonical parsed id form of the request's query text, so two spellings +of one query share their operator state. Everything else in a request is applied when output is read: hidden and collapsed items on axis categories, item order, the page selection and prune. Occupancy and column aggregates are keyed by axis **items**, so a collapse, hide, show, reorder or added item changes no operator. The visible axis is a remap. @@ -230,19 +231,19 @@ an **edge adapter**. So every edge has the same semantics: where nothing was lost. - **An edge is a session, not a connection.** An edge may be one long-lived connection, or a sequence of requests carrying the same session token or cookie, for example - several HTTP requests. The token only lets a client's requests be recognised as one - edge: the host keeps no per-client state, so what continues across connections is the - client's own watermark and shape keys. Every request can be retried, and a resync from - a watermark is idempotent. A client - asks for "notices after my watermark", and the host answers from **one shared, bounded log + several HTTP requests. The host decides nothing from the token: it is transport, and + any later authentication is out of scope. What continues across connections is the + client's own watermark and shape keys, which it sends with each request. Every request + can be retried, and a resync from a watermark is idempotent. A client asks for + "notices after my watermark", and the host answers from **one shared, bounded log of published notices**: a single log, not one per edge or client, holding the notices themselves (keys and flags, not values). A request older than the log's start is answered with a correction (below). -- **Failure.** An edge is alive while its next message or request succeeds, and each end - keeps alive in both directions. Timeouts are local monotonic durations, never compared - across machines. A side that hears nothing within its timeout, or whose request fails, - treats the connection as dropped. The client then asks for a correction from its - watermark. +- **Failure.** Timeouts are local monotonic durations, never compared across machines. + On a long-lived connection, both ends keep alive, and a host-side timeout belongs to + that open connection and is released with it. On a sequence of requests, only the + client detects failure: a request that fails or times out. In either case the client + then asks for a correction from its watermark. - **Correction is Z-set arithmetic.** A correction is `target − held`, where `target` is the current state for the client's window and `held` is what the client holds. @@ -260,7 +261,8 @@ an **edge adapter**. So every edge has the same semantics: - where the covered range also holds axis changes, relabels or flags, which positions and labels depend on, the correction carries them too, in order, as a merged notice does, so the client re-derives positions incrementally; - - only where the log no longer covers the watermark does the host fall back to `target` + - only where the log no longer covers the watermark, or the covered range holds an + oversized notice that lists no keys, does the host fall back to `target` for the whole window, and the client applies `target − held`; - a full refetch is `target − ∅`. @@ -299,7 +301,8 @@ committed command the host emits one notice to every client, addressed to none. whose later command fails keeps its earlier commands, and their notices, published. A notice carries: - the stamp `(host instance, document_generation, publication)`. The publication number - increments once per committed command, and the host instance changes on restart; + increments once per committed command. The host instance changes on restart; it is a + random id, never a wall-clock time; - axis changes, display relabels as `(id, display)`, and a flag when the formula set, `measure_agg`, the view definitions or the default view moved. A shared display's ` #2` suffix is never sent: the client computes it from the displays in scope; @@ -328,8 +331,8 @@ ADR 008's questions. **Edge adapters.** An edge that crosses a wire has one adapter at each end. Toward the circuit, the client's adapter is a sink for results and notices and a source of requests. -Toward the client it is the mirror image. Each end keeps only its timeout, and the -client's end keeps the watermark. In process, an edge is a function call. +Toward the client it is the mirror image. The client's end keeps the watermark. In +process, an edge is a function call. ### 10. Text column widths