Design 25 § 12: owners' events carry the value whole, a deleted module's entries become orphans, the first views get named tools and a live bound
Answers the second review's V1-V9 by architectural domain: the assigner's views in the new form, newer by revision alone, what a reader does when a recreate takes revisions back, a hand re-say of manifest-accepted, and the judge question under the open point on issue 1966. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
@@ -697,17 +697,23 @@ modules' names meet.
|
||||
- **The trigger is the judge's verdict** (ADR 0595 §4), heard as the indexer's event `manifest-accepted`, which
|
||||
carries the module's entries whole, so the bus module never reads the indexer's state and never polls. The indexer
|
||||
says it for every newly accepted manifest, with its entries empty when it asks for none, and the bus module reads an
|
||||
empty one as "this module asks nothing now", which is what its orphans need. It goes, as every event of the
|
||||
empty one as "this module asks nothing now", which is what its orphans need. A module whose manifest leaves the
|
||||
trunk (its directory deleted) gets an empty `manifest-accepted` too, so its entries reach `orphans` and raise
|
||||
`orphaned`; a manifest the judge set aside to wait gets none, so its entries stay asked. The indexer's tool
|
||||
`indexer_say_accepted` says `manifest-accepted` again for one module by hand, from the verdict it holds, recorded as a
|
||||
hand act, for a verdict the bus module is thought to have missed. It goes, as every event of the
|
||||
indexer, on the module events stream (ADR 0363) under the indexer's own subjects. A publish of it that fails is
|
||||
published again, and one still failing writes the indexer's finding naming the module, cleared once said (today
|
||||
the indexer only logs it). It hears the verdicts on a durable consumer, so one given while it was down is heard
|
||||
when it is back. **Its first view** at start is the indexer's
|
||||
tool `indexer_bus_state` (every accepted manifest's bus-state entries, by module and digest), asked once; the
|
||||
events keep it current after that, and a stream that keeps a verdict only for its age is never its source. A
|
||||
verdict replayed from its consumer is applied only if newer than what the first view answered for that module (by
|
||||
the manifest's digest and the indexer's revision), so a replay never takes an entry back. An `indexer_bus_state`
|
||||
verdict replayed from its consumer is applied only if newer than what the first view answered for that module, by
|
||||
the indexer's revision alone (a digest has no order), so a replay never takes an entry back. An `indexer_bus_state`
|
||||
that does not answer makes the bus module's health unhealthy, naming the verb, and is asked again on a bounded
|
||||
backoff (from 10 seconds, doubling, at most every 5 minutes); nothing is created or orphaned meanwhile. It keeps
|
||||
backoff (from 10 seconds, doubling, at most every 5 minutes); nothing is created or orphaned meanwhile. Beside the
|
||||
backoff, the bus module's tool `nats_first_view_again` asks `indexer_bus_state` at once by hand, recorded as a hand
|
||||
act. It keeps
|
||||
what it last heard per module in its own state `asked` (an old `state` section, its own kept data staying there,
|
||||
ADR 0595 §10), from which `list`, `check` and `orphans` answer; a key goes only on an empty `manifest-accepted` for
|
||||
the module, never because a manifest the judge set aside to wait is missing from the first view. Then it runs `check` over what it holds, creating what
|
||||
@@ -751,22 +757,42 @@ vault as an own secret: JetStream create and update under modules' names only (s
|
||||
no manifest form today (the assigner serves its seat verbs as tools); the form is new in mesh-sdk's manifest types
|
||||
and rides the milestone's one rebuild. Which part issues these subjects' grants first is not yet decided: the
|
||||
grants part composes every grant from the manifests, and is itself one of these readers, so its own first view
|
||||
cannot wait on a grant it has not composed (an open point, tracked on issue 1966). The owner answers at once from what it holds, as soon as its process is
|
||||
cannot wait on a grant it has not composed (an open point, tracked on issue 1966). Under the same point: which
|
||||
judge takes in the indexer's and the assigner's own new manifests, which use that form. Every manifest of the
|
||||
merge is judged by the indexer that runs, the old build, and mesh-sdk's strict decoding refuses a field it does
|
||||
not know (research 082, its Findings for question 5), so the running judge would refuse the new form; whether the
|
||||
form rides an earlier release the running judge already decodes, or the new indexer judges its own manifest, is
|
||||
not decided by a record. The owner answers at once from what it holds, as soon as its process is
|
||||
connected and before it has its own first view of any other part, with the revision of its state it answered at,
|
||||
so the indexer and the assigner, each asking the other at start, never wait on each other (§4). The reader then
|
||||
follows the owner's declared events, each carrying the revision of the state it follows, and never asks the verb
|
||||
again on a timer; a gap in revisions makes it ask once more, said in its log (§5). The owners' events are new
|
||||
families of their own, apart from the indexer's `manifest-refused` and `manifest-accepted` and the assigner's
|
||||
`put`: the indexer's `indexer.views` and the assigner's `assigner.views`, one event per changed key with its
|
||||
bucket, key and revision, kept seven days, declared in each owner's old `streams` section (its own kept data),
|
||||
so a waiter on an existing event never wakes on them. A reader that starts while its owner is down raises a
|
||||
bucket, key and revision and the key's value whole, or a delete mark for a key removed, so a reader keeps its
|
||||
picture from the events alone and asks the verb only on a gap (ADR 0615 §5). Each family is kept seven days and
|
||||
capped at 256 MiB, dropping its oldest when full (the template events); a reader that misses a dropped event sees
|
||||
the gap in revisions and asks once more. The indexer declares `indexer.views` in its old `streams` section, its
|
||||
own kept data staying there (ADR 0595 §10 names the indexer among the foundation). The assigner is not named
|
||||
there and is touched in this milestone, so it asks for `assigner.views` in the new form, as bus state of the
|
||||
template events in its `requires` (ADR 0595 §1, §11). A waiter on an existing event, `manifest-accepted` or the
|
||||
assigner's `put`, never wakes on them. **When an owner's revisions go back**: should an owner's state be rebuilt
|
||||
by the bus module's `recreate`, its revisions start again; a reader that hears a revision lower than the one it
|
||||
holds takes it as a gap and asks the first view again, and keeps what that answer says, whatever revision it held
|
||||
before. A `recreate` that could not keep the data answers empty at revision 0, so the grants part keeps its list
|
||||
in force (below): a login revoked meanwhile stays until the owner's first change, and the grants part's
|
||||
first-view condition stays raised meanwhile, naming the owner and the empty answer, cleared by an answer above
|
||||
revision 0. A reader that starts while its owner is down raises a
|
||||
condition naming the owner and the verb past its bound and keeps asking until it answers, never reading the
|
||||
owner's state instead; once it had its first view, it keeps working on what it heard (§6). The bound is longer
|
||||
than an owner's start (two minutes), so a normal start, readers and owners coming up together, notifies nobody;
|
||||
the owner's answer clears the condition. An answer that is empty at revision 0 (an owner that holds nothing yet)
|
||||
is a first view of nothing, never a reason for the grants part to drop a login it holds: it keeps the list in
|
||||
force until an answer at a revision above 0. Each reader's tools say the owner, verb and revision its first view
|
||||
holds (a read tool), and ask the first view again by hand (a re-read tool, recorded as a hand act). The
|
||||
holds, when it asked and when it was answered (a read tool), and ask the first view again by hand (a re-read tool,
|
||||
recorded as a hand act): the grants part's `grants_first_views` and `grants_first_view_again`, the tool runner's
|
||||
`runtime_first_views` and `runtime_first_view_again`, the indexer's `indexer_first_views` and
|
||||
`indexer_first_view_again`, and the assigner's `assigner_first_views` and `assigner_first_view_again`. The
|
||||
order of owner before reader is kept by the module graph's served-verb edge for the 19 readers (ADR 0614 §2), and,
|
||||
for the four, whose verb edges lie on cycles the graph leaves out (ADR 0614 §3), by the owner's answer at once and
|
||||
the reader's wait (ADR 0615 §2).
|
||||
@@ -939,9 +965,10 @@ issue 1966.
|
||||
| The bus module creates, and the binding follows | live, by tool call: a module asking for a state, a log, objects and a ledger in `requires` receives each binding in its membership, written after `created`, never before; `show` gives each entry's template, settings and fill; a module calling `create` is refused |
|
||||
| The bus module runs whole | one integration test in the nats module's repository that starts the bus module whole against the real bus server: a verdict, then `created`, then the binding in the membership; a restart that catches up a verdict given while it was down; a bucket whose settings differ raises `drifted`, the seat's `apply` of a larger cap clears it with `drift-cleared`; a refused create raises its condition and hands no binding; `recreate` and `drop` without the operator's warrant are refused, and with it act after a stream snapshot; an orphan is listed, raises `orphaned`, and goes only by `drop`; each template at a small cap refuses, events drop the oldest, and `full` is raised at the raise mark and cleared only below the clear mark; `recreated` rewrites the binding and `dropped` removes it; at start the first view from `indexer_bus_state` creates what a verdict given while it was down asked; the older remove tools refuse a new-form entry, naming `drop`'s tool |
|
||||
| A module asking bus state waits for the bus module | the module graph's table test: a manifest with a ledger entry has a requirement edge to the module providing `bus-state`, one without has none (ADR 0614 §5) |
|
||||
| A foundation part's first view | unit tests of each owner and reader (ADR 0615's How it is checked), as table cases, and these cases of the whole-module integration tests that exist today (mesh-delivery is over its integration budget, so no new test function): the indexer's (`cmd/mesh-delivery-indexer`, its one whole-module test, which the milestone's packages test merges into), the assigner's (`cmd/mesh-delivery-assigner`) and the grants part's (`cmd/mesh-grants`), and the tool runner's in mesh-tools: the owner answers its verb at once from what it holds, with its revision, before its own first view; the reader asks once at start, then only on a gap in revisions; a reader whose owner is down raises its condition only past the bound and never reads the owner's state, and the owner's answer clears it; an empty answer at revision 0 drops no login; an existing waiter on `manifest-accepted` does not wake on the new families; the read tool shows the revision each reader holds. Live, after the delivery: the indexer's count of `reads` entries on the indexer's and the assigner's state reads 0 |
|
||||
| The bus module's first view | cases in the nats module's one integration test: a replayed verdict older than the first view is not applied; an `indexer_bus_state` that does not answer turns the health unhealthy naming it and is asked again on the backoff; a set-aside manifest missing from the first view keeps its `asked` key, an empty `manifest-accepted` removes it |
|
||||
| `manifest-accepted` is never lost silently | a unit test of the indexer: a failed publish is published again, and one still failing writes the finding |
|
||||
| A foundation part's first view | unit tests of each owner and reader (ADR 0615's How it is checked), as table cases, and these cases of the whole-module integration tests that exist today (mesh-delivery is over its integration budget, so no new test function): the indexer's (`cmd/mesh-delivery-indexer`, its one whole-module test, which the milestone's packages test merges into), the assigner's (`cmd/mesh-delivery-assigner`) and the grants part's (`cmd/mesh-grants`), and the tool runner's in mesh-tools: the owner answers its verb at once from what it holds, with its revision, before its own first view; the reader asks once at start, then only on a gap in revisions; a reader whose owner is down raises its condition only past the bound and never reads the owner's state, and the owner's answer clears it; an empty answer at revision 0 drops no login; an owner's event carries the changed value whole, and a reader applies a put and a delete from the events alone and never asks the verb; a revision lower than the one held makes the reader ask its first view again; an existing waiter on `manifest-accepted` or on the assigner's `put` does not wake on the new families; the read tool shows the revision each reader holds, and the re-read tool asks once and records the hand act. Live, after the delivery: the indexer's count of `reads` entries on the indexer's and the assigner's state reads 0 |
|
||||
| A foundation part's first view comes within its bound | live, after the delivery: each reader's read tool (`grants_first_views`, `runtime_first_views`, `indexer_first_views`, `assigner_first_views`) shows, for the indexer's and the assigner's verbs, the time from its ask to the owner's answer under the two-minute bound, and no first-view condition raised by the delivery |
|
||||
| The bus module's first view | cases in the nats module's one integration test: a replayed verdict older than the first view is not applied; an `indexer_bus_state` that does not answer turns the health unhealthy naming it and is asked again on the backoff; a set-aside manifest missing from the first view keeps its `asked` key, an empty `manifest-accepted` removes it; a deleted module's entry, after its empty `manifest-accepted`, is listed by `orphans` and raises `orphaned`, and a set-aside module's entry is neither; `nats_first_view_again` asks at once and records the hand act |
|
||||
| `manifest-accepted` is never lost silently | unit tests of the indexer: a failed publish is published again, and one still failing writes the finding; `indexer_say_accepted` says it again for one module from the verdict held, and refuses a module with no accepted verdict |
|
||||
| Until the identity seat, the caller is the one the tool runner proved | a unit test of the bus module's process: a request on its tool subject naming another caller in its body acts for the proved caller; `drop` without the warrant is refused |
|
||||
| Drift and orphans, live | live, made only by a manifest change: a manifest that shrinks a setting raises `drifted`; the conditions clear as above. Nothing is filled on the live bus, and no orphan is made there |
|
||||
| Overdue and stopped are loud | live, carried by the change of the first module that moves in step 5, never by a merge made for the test alone: with the bus module's process stopped, an accepted manifest asking for an entry raises the overdue condition within five minutes, from the watchman, and a later `created` clears it; the bus module's health turns unhealthy when its pass is more than three minutes old |
|
||||
|
||||
Reference in New Issue
Block a user