Designs 25 and 55 answer the review by architectural domain: the bus module's events on its old sections, overdue creation raised by the watchman, the proven author, events and the database caught up after a restart, the bus module's integration test
This commit is contained in:
+3
-1
@@ -117,6 +117,8 @@ downstream of Module and Placement. **Decided by** ADR 0262, 0277, 0348.
|
||||
**Uses:** module, node, manifest (Module), assignment (Placement), provision (Provisioning), proposal
|
||||
(Operator and conversation).
|
||||
|
||||
- **template file** — a file a module ships with placeholders, such as `${config:<key>}`, which the provisioner
|
||||
client fills on each node (ADR 0349). Never a template of bus state (see [Homonyms](#homonyms)).
|
||||
- **config value** — anything a module reads that someone may change: a font size, a domain, an address.
|
||||
A module declares every one it reads under `config` in its manifest, with a type, a description,
|
||||
validation, whether it is trusted, optionally the predefined key it falls back to, and a default or
|
||||
@@ -1101,7 +1103,7 @@ renaming one sense, the old sense moves to a *Not:* line and becomes mechanical.
|
||||
| snapshot | the latest state of one ledger instance, from which a rebuild starts | **snapshot** of a ledger's state | Data |
|
||||
| | the bus's own backup of each stream | **stream snapshot** | Data |
|
||||
| template | a storage type with a configuration, asked for in `requires` | **template** of bus state | Data |
|
||||
| | a file with placeholders a provisioner fills | **template file** | Config, Provisioning |
|
||||
| | a file with placeholders a provisioner fills | **template file** | Config |
|
||||
| option | a setting of a template a module may change | **option** of a template | Data |
|
||||
| | one choice of an ask to a person | an ask's **option** | Operator and conversation |
|
||||
| effect | what an operation does to a ledger's state | **ledger effect** | Data |
|
||||
|
||||
@@ -672,6 +672,7 @@ full, and the judge refuses a manifest that gives it:
|
||||
| log | stream | refuses when full; never rewritten; an entry at most 256 KiB; one subject per key | cap 1 to 8192 MiB (1024); age 1 to 3650 days (none) |
|
||||
| objects | object store | refuses when full; kept for good | cap 1 to 8192 MiB, required; a grant |
|
||||
| ledger | ledger | as log, plus its type and a snapshot per instance; its state and index buckets as state | cap; keeping days only in a ledger's own configuration |
|
||||
| (none: a bare stream) | stream | the module's own subjects; within the mesh's bounds | its own configuration, which must give "when full" (refuse or drop the oldest), a cap of 1 to 8192 MiB and an age of 1 to 3650 days or none, and may give a grant; the judge refuses one missing any of the three |
|
||||
|
||||
The template log is the **module log** of ADR 0297. The mesh, never the module, names the bus objects and their
|
||||
subjects (ADR 0201 §4): `<module>_<local name>`, and a local name holding the separator is refused so no two
|
||||
@@ -690,14 +691,23 @@ modules' names meet.
|
||||
```
|
||||
|
||||
- **The trigger is the judge's verdict** (ADR 0595 §4), heard as an event that carries the module's entries whole,
|
||||
so the bus module never reads the indexer's state and never polls. The judge checks every entry once, at the merge
|
||||
so the bus module never reads the indexer's state and never polls. It hears the verdicts on a durable consumer, so
|
||||
one given while it was down is heard when it is back, and at start it runs `check` over every accepted manifest,
|
||||
creating what is missing. The judge checks every entry once, at the merge
|
||||
check and at take-in (ADR 0578; ADR 0595 §8).
|
||||
- **The bus module has a process of its own** beside its tool bundle, with a declared health check. Its credential
|
||||
creates streams and buckets under modules' names only, and deletes only through `drop`.
|
||||
creates streams and buckets under modules' names only, and deletes only through `drop` and `recreate`. Its health
|
||||
turns unhealthy, naming the cause, when its last pass over the verdicts or over fill is more than three minutes
|
||||
old, so the only guard against a store filling never stops without a sound; another module's entry at 75 percent
|
||||
raises that module's condition and leaves the bus module healthy.
|
||||
- **The binding travels on `created`** (ADR 0595 §1, §7). The grants part, which issues every membership, hears it
|
||||
and writes the binding (the names on the bus) into the module's membership, so no part writes another's state.
|
||||
on a durable consumer and writes the binding (the names on the bus) into the module's membership, kept in its own
|
||||
state `memberships`, so no part writes another's state and a binding outlives the 30 days its event is kept.
|
||||
A module whose binding is missing at start fails loudly, naming the entry; it never starts blind. A `refused`
|
||||
create hands no binding, and a refused or overdue creation raises a condition naming the module and the entry.
|
||||
create hands no binding. **A refused or overdue creation is loud**: overdue means no `created` or `refused` within
|
||||
five minutes of an accepted verdict that asks for the entry. The condition is raised by the watchman, which already
|
||||
hears the judge's verdicts, never by the bus module, which cannot raise it while it is down; it names the module
|
||||
and the entry, and a later `created` clears it.
|
||||
- **Only the owner reaches it** (ADR 0596 §2). The membership grants the owner's account its own entries and no
|
||||
other module's: the new form has no readers. What another module needs of that data it asks through the owner's
|
||||
tools or seat verbs, and what the owner lets others hear is its declared events, subscribed to through
|
||||
@@ -726,20 +736,32 @@ only on the operator's warrant (ADR 0259 §6), asked through the operator channe
|
||||
the bus module takes a stream snapshot of the entry. A drifted entry is said, never quietly fixed: only a difference
|
||||
that grows is applied without a person.
|
||||
|
||||
**Events**: `created`, `refused` (with why), `drifted` and `drift-cleared`, `full` and `full-cleared`, `orphaned`;
|
||||
**Events**: `created`, `refused` (with why), `drifted` and `drift-cleared`, `full` and `full-cleared`, `orphaned`
|
||||
(cleared by a `drop`, or by a manifest asking for the entry again, which emits `created` for it);
|
||||
each carries the module, the local name, the bus name, the template, and the settings asked against those held. The
|
||||
bus module asks for them with the template events at 30 days, the bound's top, because a drift or an orphan is read
|
||||
back days later by a person; the conditions hold the live state. This settles where they are kept, which
|
||||
ADR 0595 §12 left to the design.
|
||||
bus module's own kept data stays on the old sections (ADR 0595 §10), because it cannot wait for its own process to
|
||||
create it: it declares this stream in its `streams` section, kept 30 days (ADR 0363's bound), created by the grants
|
||||
part as today, with a cap of 256 MiB; it drops its oldest when full, which loses no live state, because every drift,
|
||||
orphan and fill stands as a condition until it clears. Thirty days, because a drift or an orphan is read back days later by a person; the conditions hold the
|
||||
live state. The tool `history` of one entry reads them back: every event the bus module said of it, in order. This
|
||||
settles where they are kept, which ADR 0595 §12 left to the design.
|
||||
|
||||
**Fill is the bus module's one periodic read** (ADR 0595 §6): every minute, for every entry that refuses when full,
|
||||
because the bus says nothing as a store fills. The condition `full` is raised from 75 percent of the cap and cleared
|
||||
below it. The grants part's `mesh-grants.history-full` moves to it: the new condition is raised first, then the old
|
||||
key cleared.
|
||||
key cleared. A bare stream that refuses when full is read the same way. **The conditions**, each naming the module
|
||||
and the entry: `full` (cleared below 75 percent), `drifted` (cleared by `drift-cleared`), `orphaned` (cleared by a
|
||||
`drop` or by a manifest asking for it again) and a refused create (cleared by a later `created`).
|
||||
|
||||
**Its tools** (tools-are-how-a-module-is-spoken-to): the four reading verbs answer every entry the bus module
|
||||
created and its fill; `create`, `apply`, `recreate` and `drop` are its tools for a person, the last two asking the
|
||||
warrant; its health names the process's last pass, the entries it could not create, and the entries over 75 percent.
|
||||
**Its tools** (tools-are-how-a-module-is-spoken-to): the four reading verbs, marked reads, answer every entry the
|
||||
bus module created and its fill, and `history` its events for one entry; `create` and `apply`, marked acts, and
|
||||
`recreate` and `drop`, marked dangerous and so granted only by name (ADR 0386 §6, ADR 0387), are its tools for a
|
||||
person. Such a tool, in the bus module's bundle, holds no grant of those verbs' subjects, and neither does the tool
|
||||
runner's account: it hands the request to the process on the process's own tool subject, carrying the caller the
|
||||
bus proved, and the process acts only for a caller whose role grants that tool, for `recreate` and `drop` only once
|
||||
the operator's warrant is held, and answers what it did. The bus seat's `apply` (a difference that grows) and the
|
||||
ledger's `apply` (§ 12.4) are two verbs on two subjects, granted apart; this design writes them qualified. Its health
|
||||
names the process's last pass, the entries it could not create, and the entries over 75 percent.
|
||||
|
||||
### 12.4 The ledger
|
||||
|
||||
@@ -772,13 +794,19 @@ key-value buckets, and asked for with the template ledger.
|
||||
another writer, `apply` answers success with its operation's sequence and re-reads, never appending again.
|
||||
- **A full state bucket loses no operation** (§6): `apply` answers that the operation is taken, with its sequence,
|
||||
and that the state is behind because the bucket is full; the next `apply` after room is made catches it up.
|
||||
- **The author is proven** (§7): `apply` stamps the owning module's authenticated account and the author it passes
|
||||
on, the account that called the owner's tool, never words the caller chose.
|
||||
- **The author is proven** (§7): `apply` stamps the owning module's authenticated account and the account that
|
||||
called the owner's tool. The owner passes that author on by naming the tool call it serves: the tool runner, which
|
||||
served that call and proved its caller, stamps the caller it proved, so the module cannot set the author to words of
|
||||
its own; an `apply` naming no call in flight carries the owner's account alone, and one naming another module's
|
||||
call is refused. A copy of old records (design 55 § 8.1) is stamped with the owner's account and keeps the old
|
||||
author as a separate field marked imported, never as the proven author.
|
||||
- **Every instance has a snapshot** (§8): the latest state on a subject of its own, never expiring, written by every
|
||||
`apply`. It makes a kept ledger's rebuild fast and an expiring ledger's possible; a repair that finds it behind
|
||||
the state rewrites it.
|
||||
- **Only the tool runner's ledger credential publishes on a ledger's history** (§9): one per module, held by the
|
||||
tool runner and never by the module's own code, whose account may read its ledger and not publish on it. Only the
|
||||
tool runner and never by the module's own code, whose account may read its ledger and not publish on it. The grants
|
||||
part issues it with the module's membership on that machine, scoped to the subjects of that module's ledger
|
||||
histories and snapshots, and removes it when the module is unassigned from the machine. Only the
|
||||
owner's account reads the history, the snapshot and the state.
|
||||
- **An index** is a second key-value bucket kept by a watcher in the owning module's process, rebuildable from the
|
||||
history; it raises a condition when it lags behind (§4).
|
||||
@@ -789,16 +817,22 @@ The new calls live in a small mesh-sdk package of their own, served by the tool
|
||||
modules that use them; the module library, which 112 modules import, does not change (ADR 0595 §9). They are the
|
||||
object store's (put, get, list, delete, info, watch); a stream's read-back and fill; a work queue's size and dead
|
||||
letters; and the ledger's: `apply`, `get`, `history`, `watch`, `query`, and its repairs `rebuild` (the state from
|
||||
the history or the snapshot), `reindex`, `snapshot` and `lag` (ADR 0597 §10). mesh-sdk's catalog and membership
|
||||
the history or the snapshot), `reindex`, `snapshot` and `lag` (ADR 0597 §10). The tool runner serves the repairs as
|
||||
tools of every module that owns a ledger, limited to its own ledgers, so no owner declares them and the next ledger's
|
||||
owner has them on its first day. mesh-sdk's catalog and membership
|
||||
packages change once for the typed `requires` entry and the binding, rebuilding about 30 modules.
|
||||
|
||||
### 12.6 The move, and the order of the build
|
||||
|
||||
**The build, each step undoable on its own** (ADR 0595 §10): (1) mesh-sdk's typed `requires`, binding and calls
|
||||
package; (2) the judge's rules; (3) the bus module's process, verbs and events, creating only for the new form; (4)
|
||||
the tool runner's calls, `apply` and its ledger credential among them; (5) modules move, each owner first. Undoing
|
||||
step 3 leaves what it created in place, and a module moved after it fails loudly on its missing binding. The
|
||||
placement holds a moved module off a machine whose tool runner does not read the typed binding, and says so.
|
||||
package; (2) the judge's rules; (3) the bus module's process, verbs and events, creating only for the new form, with the grants part's writing of
|
||||
the binding on `created`; (4) the tool runner's calls, the ledger's `apply` and its ledger credential among them; (5)
|
||||
modules move, each owner first. Each undo: undoing step 2 refuses the new form again, which no module uses before
|
||||
step 5; undoing step 3 leaves what it created in place, and a module moved after it fails loudly on its missing
|
||||
binding; undoing step 4 leaves a moved module without its calls, which the placement holds off that machine. The
|
||||
placement holds a moved module off a machine whose tool runner does not serve the typed binding and the calls the
|
||||
module asks for (a ledger's `apply` among them), and says so; where the placement reads what a tool runner serves is
|
||||
left to the build of step 4 and tracked on issue 1966.
|
||||
|
||||
**A module moves when it is next touched** (ADR 0595 §11), keeping its local names and carrying its old settings
|
||||
as options, so its bus objects and data stay and no drift is raised. It asks for each entry once: an old section
|
||||
@@ -820,13 +854,23 @@ are tracked by issue 1966.
|
||||
|---|---|
|
||||
| A manifest's bus state is valid, once | the judge's unit tests, each refusal naming the field: an unknown template, an option outside its bound, past values 0, "when full" given, a fixed setting given, a name used twice across storage types, two modules' bus names alike, a `reads` in the new form, an effect outside the fixed set (ADR 0595 §8, ADR 0596 §2, ADR 0597 §2) |
|
||||
| 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 |
|
||||
| Drift, orphans and the warrant | live: a bucket whose settings differ raises `drifted` and its condition; `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; an orphan is listed, raises `orphaned`, and goes only by `drop`, after a stream snapshot |
|
||||
| Full | live: each template at its cap refuses, events drop the oldest; `full` raised at 75 percent and cleared below |
|
||||
| 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 75 percent and cleared below |
|
||||
| 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: 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 |
|
||||
| A person's tools reach the process, and only by role | live: a role without the dangerous grant is refused `drop`'s tool; the tool runner's account holds no grant of `create`, the seat's `apply`, `recreate` or `drop` |
|
||||
| The author is the proven caller | the ledger's integration test: an `apply` naming another module's tool call is refused; the author stamped is the caller the tool runner proved, whatever the module passed |
|
||||
| Only the owner reaches its data | live: another module's account reading an entry in the new form, a ledger's history, snapshot or state among them, is refused; a raw publish on a ledger's history is refused |
|
||||
| The ledger keeps its promises | one integration test against the real bus (ADR 0597's How it is checked): two writers race and one is refused; two interleaved applies leave the state at the higher sequence; a write cut between history and state is repaired; a full state bucket answers taken with its sequence and catches up; an idle instance whose operations expired rebuilds from its snapshot; `rebuild`, `reindex` and `lag` repair by hand; a forged author is refused; every `apply` leaves the snapshot equal to the state; an index behind raises its condition and `reindex` clears it |
|
||||
| Only the owner applies | the ledger's integration test: another module's ledger `apply` on the knowledge base's ledger is refused |
|
||||
| A bare stream is complete | the judge's unit test: a bare stream missing "when full", a cap or an age is refused, naming the field |
|
||||
| The calls rebuild only their users | a read of the delivery plan: only the importers of the calls package rebuild when it changes |
|
||||
| The move keeps data | live: a module moved from `state` keeps its bucket and data and raises no drift; a new entry in an old section is still created by the grants part; the count falls by one; at 0 a manifest using the section is refused and the foundation's are still accepted; a moved module is held off a machine whose tool runner does not read the typed binding |
|
||||
|
||||
**The test budget** (50 integration and 500 unit tests per repository): the design adds one integration test in the
|
||||
nats module's repository and one in mesh-tools (the ledger), and table cases, not new functions, to the judge's unit
|
||||
tests in mesh-delivery and to mesh-sdk's decoding tests. Each repository's count against the budget is read in the
|
||||
prepare step of issue 1966, and a repository over it merges tests to stay within it.
|
||||
|
||||
**Acceptance.** The operator asks the bus module's `list` and sees every module's kept data with its template, its
|
||||
settings and its fill; a module that moved keeps its data; a drift or an orphan reaches the operator as a condition
|
||||
and is changed only on their word; and the knowledge base keeps its records as a ledger (design 55 § 10).
|
||||
|
||||
@@ -78,7 +78,7 @@ and the knowledge base works out each design's state (ADR 0423, ADR 0424).
|
||||
│ digest and the sequence of their write-section
|
||||
│ state asked one key per part asked of the judge and not yet answered: ticket, node, when
|
||||
│ state findings the whole-set findings standing now, and the told marks (told.<topic>)
|
||||
│ events reviews one message per part reviewed: the digest judged, the verdict, the findings
|
||||
│ stream reviews one message per part reviewed: the digest judged, the verdict, the findings
|
||||
├ written through the tool runner's apply on the control-node, the only publisher on the
|
||||
│ ledger's history (ADR 0597 §3, §9)
|
||||
├ in its memory the search index, built from the bus at start and kept by watching the
|
||||
@@ -116,15 +116,23 @@ is one operation the module hands to `apply`: among them `reserve`, `propose`, `
|
||||
`withdraw`. The module checks its own rules first (an `accept` needs the operator's Approve where the record needs
|
||||
it, § 5; only the author writes a draft, § 4), then calls `apply`, which checks the operation against the record's
|
||||
type, appends it to the instance's history with the sequence it expects, derives the head by the operation's effect,
|
||||
and writes the head and its snapshot. The author is the account the bus proved for the caller of the module's verb,
|
||||
passed on by the module and stamped by `apply`, never a name the caller gave (ADR 0597 §7).
|
||||
and writes the head and its snapshot. The author is the account the bus proved for the caller of the module's verb:
|
||||
the module names the tool call it serves, and the tool runner stamps the caller it proved for it, never a name the
|
||||
caller or the module gave (ADR 0597 §7; [design 25](25-the-bus-on-nats.md) § 12.4).
|
||||
|
||||
**Every operation's event is sent once, after a restart too.** `apply` emits nothing; the module sends the event of
|
||||
each operation it applied (`submitted`, `reviewed` and the rest) with the operation's sequence as the message's
|
||||
id, so the bus drops a second send, and keeps the last sequence it sent per record in the state `findings`
|
||||
(`sent.<kind>.<number>`). At start it sends the events of every later operation in each record's history, so a
|
||||
module stopped between `apply` and its event loses none, and a consumer of `mesh-knowledge.reviewed` never waits for
|
||||
one that was never sent.
|
||||
|
||||
**A write is whole or refused, and an operation commits when its history takes it** (ADR 0597 §5, §6, changing
|
||||
ADR 0592 §10). The commit point of every change to a record is the operation appended to the ledger's history: a
|
||||
failure before it is appended refuses the call, and nothing is taken; a racing writer is refused by the bus, which
|
||||
expects the history's last sequence for the instance. Once it is appended, the call answers that it is taken, with
|
||||
its sequence; the head is derived by `apply` as an update of the revision it read, and a head behind its history is
|
||||
caught up by the next `apply` or read. A full state bucket answers that the operation is taken and the head behind,
|
||||
caught up by the next `apply` (ADR 0597 §6). A full state bucket answers that the operation is taken and the head behind,
|
||||
never that it was refused. So nothing an author was told was refused takes effect later. A reservation is an
|
||||
operation `reserve` on an instance with no history, so two sessions reserving at once get two numbers or one
|
||||
refusal. The module's other state (`drafts`, `asked`, `findings`) keeps the compare-and-set on the key's revision,
|
||||
@@ -169,7 +177,7 @@ waiting more than 30 minutes. A part waiting more than 30 minutes is asked of th
|
||||
channel, and the ask clears when the part is judged; the module stays healthy meanwhile, because a record waiting on
|
||||
its review is not the module failing (issue 508). The condition at 75 percent of a cap is the bus module's (ADR 0595 §6; [design 25](25-the-bus-on-nats.md) § 12).
|
||||
|
||||
**Events** (ADR 0592 §34) are kept 30 days; what a later reader needs is also in the version message. Each carries:
|
||||
**Events** (ADR 0592 §34) are kept 30 days; what a later reader needs is also in the `submit` operation, in the ledger's history. Each carries:
|
||||
|
||||
| Event | Carries |
|
||||
|---|---|
|
||||
@@ -249,12 +257,15 @@ costs only the sections it changes; the forms of ADR 0592 §1 to §9 that it rep
|
||||
- **The history** is kept for good: the ledger template's history refuses a new operation when full, rather than
|
||||
dropping its oldest, and the bus module raises its condition at 75 percent of the cap (ADR 0595 §3, §6). Each
|
||||
instance's snapshot, the latest head on a subject of its own, makes a rebuild fast (ADR 0597 §8).
|
||||
- **A draft** is a key in the state `drafts` (§ 4). **A part's verdict** is a message on the stream `reviews`, and a
|
||||
part asked of the judge and not yet answered a key in the state `asked` (§ 5). **The whole-set findings** standing
|
||||
- **A draft** is a key in the state `drafts` (§ 4). **A part's verdict** is the operation `review` on the record's
|
||||
history first, then a message on the stream `reviews`; a `review` with no message on `reviews` is sent at start
|
||||
with the operation's sequence as its id, so the consumers of `reviews` miss none and hear none twice. A part
|
||||
asked of the judge and not yet answered a key in the state `asked` (§ 5). **The whole-set findings** standing
|
||||
now are keys in the state `findings`, and what was told to the operator once is a key `told.<topic>` there. These
|
||||
keep their own forms (ADR 0597 §12), asked for in `requires`: the states by the template state; `reviews`, kept for
|
||||
good and heard only where granted (ADR 0592 §6, §8), as a bare stream with its own configuration (kept for good,
|
||||
refusing when full, a grant), because no template both keeps for good and takes a grant (ADR 0595 §2).
|
||||
refusing when full, a grant), because no template both keeps for good and takes a grant (ADR 0595 §2); the bus module's read of fill every minute
|
||||
covers it like any entry that refuses when full.
|
||||
|
||||
**Caps** (ADR 0592 §25, its object bucket's cap lapsing by ADR 0597 §12). Each is set from the move's dry run, within
|
||||
its template's bound (ADR 0595 §3): a history at most 8192 MiB, a state or a ledger's state at most 64 MiB. The
|
||||
@@ -270,6 +281,12 @@ starting figures, from today's 83 MB for 736 records with every version copying
|
||||
|
||||
A write refused at a cap names the cap, and the module's health turns unhealthy naming it.
|
||||
|
||||
**The ledger's state is the tightest cap.** 64 MiB is already the template's top. A head holds no text, only fields,
|
||||
clauses, links and its sections' titles and digests; estimated at most 8 KiB for a usual record, the 736 heads of
|
||||
today need about 6 MiB, and about 1000 once designs and glossary entries become records (slice 3, § 9) about 8 MiB.
|
||||
Those are estimates; the move's dry run measures the real total, and a total above 32 MiB is told to the operator
|
||||
before the move.
|
||||
|
||||
**Nobody else reads any of it** (ADR 0596 §2, ADR 0597 §9, changing ADR 0592 §8 and §9). Only the knowledge base's
|
||||
own account reads its ledger's history, snapshot and state and its other kept data; the ledger's history is published
|
||||
on only by the tool runner's ledger credential. Another module asks the knowledge base's verbs (`get`, `history`,
|
||||
@@ -494,7 +511,7 @@ field by field and section by section, and the result is written on issue 426.
|
||||
### 8.1 The move off the store
|
||||
|
||||
The records leave the store once, and the database is dropped only after a check and the operator's yes
|
||||
(ADR 0592 §12 to §16, the forms copied into changed by ADR 0597 §12):
|
||||
(ADR 0592 §12 to §16; the forms the records are copied into are those of ADR 0597 §12):
|
||||
|
||||
1. **Order.** The ledger is built first, in the order of ADR 0595 §10: mesh-sdk's typed `requires`, binding and
|
||||
package of the new calls; the indexer's judge's rules; the bus module's process, verbs and events; the tool
|
||||
@@ -508,7 +525,9 @@ The records leave the store once, and the database is dropped only after a check
|
||||
2. **Copy.** The move copies everything the database holds onto the bus, every record, version, clause, link,
|
||||
review, finding, ask with its warrant, reservation and told mark: each record's versions as operations on its
|
||||
instance in the ledger, in order (a `write-section` for each section a version changed, then its `submit`, then
|
||||
the record's review, ask, warrant and acceptance), through `apply`, so each head is derived and never copied;
|
||||
the record's review, ask, warrant and acceptance), through `apply`, so each head is derived and never copied; each operation is stamped with the knowledge base's own
|
||||
account and keeps the database's author as a separate field marked imported, which `history` shows as the author
|
||||
of an imported version;
|
||||
each standing finding into `findings`, each told mark as `told.<topic>`. A clause keeps its number, status and source as the database holds
|
||||
them (ADR 0321). It emits `moved` per record, writes nothing twice, and a second run changes nothing and says so.
|
||||
A dry run lists what it would write and the size each bucket and stream will need, from which the caps are set.
|
||||
@@ -523,9 +542,20 @@ The records leave the store once, and the database is dropped only after a check
|
||||
bus, so a restart never falls back to the database. A difference is told to the operator, and the module stays on
|
||||
the database.
|
||||
6. **Rollback.** Until the database is dropped, the module writes each change to the database too, after `apply`
|
||||
has taken its operation, so a rollback of the delivery reads a current database; a write the database refuses
|
||||
after the ledger took it is retried and, past its tries, raises a condition naming the record, never answered as
|
||||
refused. A rollback is safe only until the drop. This settles the rollback ADR 0597 §13 left to the design.
|
||||
has taken its operation, so a rollback of the delivery reads a current database. What the database holds is
|
||||
kept as a key in the state `findings`, `database.sequence`: the last history sequence written to it. At start,
|
||||
and after a write the database refused, the module catches the database up from the history from that sequence
|
||||
on, so a restart between `apply` and the database write loses nothing. A database still behind after three tries
|
||||
raises the condition `database-behind`, naming each record it lacks and saying that a rollback now would lose
|
||||
them, and never answers the author that the write was refused; the module's health is unhealthy while it stands,
|
||||
the drop (step 8) is refused while it stands, and the catch-up tool copies the records again from the ledger and
|
||||
clears it. A rollback is a person's act, and the condition is what tells them it is unsafe. **After a rollback**,
|
||||
the older module wrote to the database alone: beside `database.sequence` the module keeps the newest version the
|
||||
database held when it last wrote there, and a forward delivery that finds a newer version in the database refuses
|
||||
every writing verb,
|
||||
copies the changed records from the database onto the ledger as operations, runs the check of step 4 again, and
|
||||
serves writes only once it is clean. A rollback is safe
|
||||
only until the drop. This settles the rollback ADR 0597 §13 left to the design.
|
||||
7. **Tell and ask.** Once the check is clean, the operator is told its result and asked, once, whether the database
|
||||
may be dropped, because dropping it removes data.
|
||||
8. **Drop.** On the operator's yes, the delivery after it removes the module's requirement of a database, and the
|
||||
@@ -653,7 +683,7 @@ table-driven; one integration test starts the module whole against the real bus
|
||||
| two writes race on one draft | unit: the second compare-and-set loses, is retried, and is refused with the reason past its tries |
|
||||
| `submit` races `take-over` | unit: one wins; the other is refused naming the new author or the new version |
|
||||
| two reservations race | unit: two numbers, or one refused; never one number twice |
|
||||
| a write cut between the history and the head | the ledger's integration test (design 25 § 12): the call answered that the operation is taken; the next `apply` or read derives the head; the module sends the event once |
|
||||
| a write cut between the history and the head | the ledger's integration test (design 25 § 12.7): the call answered that the operation is taken; the next `apply` derives the head. The module's own integration test: stopped after `apply`, restarted, it sends the event once |
|
||||
| a failure before the operation is appended | unit: the call is refused, and no head, event or version follows later |
|
||||
| a change through the bus during the move | unit: read back from the database, so a rollback of the delivery reads a current database (ADR 0592 §14) |
|
||||
| a section changed after the operator's Approve | unit: the record is asked again; a version with every section unchanged is not (ADR 0592 §21) |
|
||||
@@ -674,8 +704,12 @@ table-driven; one integration test starts the module whole against the real bus
|
||||
| a form-only version | unit: accepted when only names and links changed and each target resolves; refused otherwise |
|
||||
| an unproven caller | unit: `open`, `write`, `submit`, `propose` and `take-over` refuse it |
|
||||
| the index behind | unit: health unhealthy while the index's sequence is behind the ledger's state; `ask` refuses "index not built" |
|
||||
| a forward delivery after a rollback | unit: a database changed by the older module is found, the writing verbs refused, the changes copied and checked, then writes served |
|
||||
| a restart between `apply` and the database write | unit: the module is stopped after `apply` and before the database write, restarted, and the database matches the history; health showed it behind meanwhile |
|
||||
| the database refuses past its tries | unit: `database-behind` names the record; the drop is refused while it stands; the catch-up tool clears it |
|
||||
| a restart between `apply` and its event | unit: the module is stopped after `apply` of a `review`, restarted, and sends one `reviewed`; a second start sends none |
|
||||
| the move as operations | unit: each record's versions copied as `write-section` and `submit` operations in order; the derived head equals the database's; a second run appends nothing |
|
||||
| the start | integration: the time to a built index measured and reported |
|
||||
| the start | integration: the time to a built index measured and reported, failing above 40 seconds, the estimate's top |
|
||||
| A section is a part with a title | a table test, one case per refused name and text of § 2.2; a form-only version whose text changed beyond its links is refused |
|
||||
| Every bucket has a tool, and health says the index | the manifest test compares tools and events with the code; a unit test of the health before and after the index is built |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user