bus5 K27 (§681): mesh-broker's snapshot-get, snapshot-restore, snapshot-restore-cancel, snapshot-remove and snapshot-restored; the format's verb word chunks

Builds: design 47 G §681, §691, A-44
This commit is contained in:
2026-11-11 22:37:57 +01:00
parent 3658ceb1b6
commit cf5590c759
8 changed files with 645 additions and 19 deletions
+4
View File
@@ -354,6 +354,10 @@
"by-caller": {
"type": "boolean",
"description": "the holder's process answers the verb itself and tells callers apart by the account the bus proved (ADR 0259 3; design 47 G 554, 621, 656)"
},
"chunks": {
"type": "boolean",
"description": "the holder's process sends the answer's file in chunks on mesh.seat.<seat>.chunk.<verb>.<call>.<n>, each acknowledged by the caller on mesh.seat.<seat>.ack.<verb>.<call>.<n>; only with by-caller (design 47 G 681)"
}
}
},
+137 -19
View File
@@ -3,40 +3,47 @@
// Package meshbroker is the contract of the seat "mesh-broker", defined whole (seats/mesh-broker/seat.json): The mesh's bus, and the bus state modules ask of it in requires (design 25 § 12). create, apply, recreate and drop are granted to the bus module's own credential alone.
package meshbroker
import "time"
// Seat is the seat's name.
const Seat = "mesh-broker"
const (
VerbList = "list"
VerbShow = "show"
VerbCheck = "check"
VerbOrphans = "orphans"
VerbCreate = "create"
VerbApply = "apply"
VerbRecreate = "recreate"
VerbDrop = "drop"
VerbList = "list"
VerbShow = "show"
VerbCheck = "check"
VerbOrphans = "orphans"
VerbCreate = "create"
VerbApply = "apply"
VerbRecreate = "recreate"
VerbDrop = "drop"
VerbSnapshotGet = "snapshot-get"
VerbSnapshotRestore = "snapshot-restore"
VerbSnapshotRestoreCancel = "snapshot-restore-cancel"
VerbSnapshotRemove = "snapshot-remove"
)
const (
EventCreated = "created"
EventRefused = "refused"
EventDrifted = "drifted"
EventDriftCleared = "drift-cleared"
EventFull = "full"
EventFullCleared = "full-cleared"
EventOrphaned = "orphaned"
EventRecreated = "recreated"
EventDropped = "dropped"
EventCreated = "created"
EventRefused = "refused"
EventDrifted = "drifted"
EventDriftCleared = "drift-cleared"
EventFull = "full"
EventFullCleared = "full-cleared"
EventOrphaned = "orphaned"
EventRecreated = "recreated"
EventDropped = "dropped"
EventSnapshotRestored = "snapshot-restored"
)
// Verbs is every verb the seat serves, in its definition's order: a new copy each call.
func Verbs() []string {
return []string{VerbList, VerbShow, VerbCheck, VerbOrphans, VerbCreate, VerbApply, VerbRecreate, VerbDrop}
return []string{VerbList, VerbShow, VerbCheck, VerbOrphans, VerbCreate, VerbApply, VerbRecreate, VerbDrop, VerbSnapshotGet, VerbSnapshotRestore, VerbSnapshotRestoreCancel, VerbSnapshotRemove}
}
// Events is every event published on the seat's subject: a new copy each call.
func Events() []string {
return []string{EventCreated, EventRefused, EventDrifted, EventDriftCleared, EventFull, EventFullCleared, EventOrphaned, EventRecreated, EventDropped}
return []string{EventCreated, EventRefused, EventDrifted, EventDriftCleared, EventFull, EventFullCleared, EventOrphaned, EventRecreated, EventDropped, EventSnapshotRestored}
}
// Family is where the seat's events are kept: the shared events stream, filtered to the seat's subjects.
@@ -72,6 +79,17 @@ const SubjectRecreated = "mesh.seat.mesh-broker.event.recreated"
// SubjectDropped is where dropped is published.
const SubjectDropped = "mesh.seat.mesh-broker.event.dropped"
// StreamSnapshotRestored is the stream snapshot-restored is kept in.
const StreamSnapshotRestored = "SEAT_mesh-broker_snapshot-restored"
// SubjectSnapshotRestored is where snapshot-restored is published, on mesh.seat.mesh-broker.event.snapshot-restored.<request>.<act>.
func SubjectSnapshotRestored(request, act string) string {
return "mesh.seat.mesh-broker.event.snapshot-restored." + request + "." + act
}
// SubjectSnapshotRestoredAll hears every snapshot-restored.
const SubjectSnapshotRestoredAll = "mesh.seat.mesh-broker.event.snapshot-restored.*.*"
// Binding is the binding a module receives in its membership for one entry (ADR 0595 §1, §7): the names on the bus of the entry's objects, one form in the events, in list, show and orphans, and in the membership.
type Binding struct {
// a key-value bucket's name
@@ -364,6 +382,91 @@ type DropAnswer struct {
Snapshot string `json:"snapshot,omitempty"`
}
// SnapshotGetInput is what snapshot-get takes.
type SnapshotGetInput struct {
// 128 random bits the caller chooses: the subject token of this send's chunks and acknowledgements
Call string `json:"call"`
// the snapshot's request: the id of the request the keeper took it for, in its state requests
Request string `json:"request"`
}
// SnapshotGetAnswer is what snapshot-get answers.
type SnapshotGetAnswer struct {
// when the snapshot was taken, RFC 3339
At *time.Time `json:"at,omitempty"`
// how many chunks are sent; 0 when the caller is granted no chunk subjects
Chunks int64 `json:"chunks,omitempty"`
// sha256: of the file's bytes
Digest string `json:"digest,omitempty"`
// why not: snapshot damaged, snapshot missing, snapshot protected or snapshot taken before milestone G; set alone
Error string `json:"error,omitempty"`
// the entry's local name
Local string `json:"local,omitempty"`
Module string `json:"module,omitempty"`
Request string `json:"request,omitempty"`
Size int64 `json:"size,omitempty"`
// the stream's name on the bus
Stream string `json:"stream,omitempty"`
}
// SnapshotRestoreInput is what snapshot-restore takes.
type SnapshotRestoreInput struct {
// the snapshot's request: the id of the request the keeper took it for, in its state requests
Request string `json:"request"`
// check the file against its digest and restore nothing
Verify bool `json:"verify,omitempty"`
// why, which the hand-act log keeps
Why string `json:"why"`
}
// SnapshotRestoreAnswer is what snapshot-restore answers.
type SnapshotRestoreAnswer struct {
// accepted: the act's id
Accepted string `json:"accepted,omitempty"`
// busy: the id of the act that runs; it keeps no queue
Busy string `json:"busy,omitempty"`
// why not; set alone
Error string `json:"error,omitempty"`
}
// SnapshotRestoreCancelInput is what snapshot-restore-cancel takes.
type SnapshotRestoreCancelInput struct {
// the restore's act id
Act string `json:"act"`
// why, which the hand-act log keeps
Why string `json:"why"`
}
// SnapshotRestoreCancelAnswer is what snapshot-restore-cancel answers.
type SnapshotRestoreCancelAnswer struct {
// accepted: the act's id
Accepted string `json:"accepted,omitempty"`
// busy: the id of the act that runs; it keeps no queue
Busy string `json:"busy,omitempty"`
// why not; set alone
Error string `json:"error,omitempty"`
}
// SnapshotRemoveInput is what snapshot-remove takes.
type SnapshotRemoveInput struct {
// true: every snapshot past snapshot-keep-days
Expired bool `json:"expired,omitempty"`
// the snapshot's request; or expired true, not both
Request string `json:"request,omitempty"`
// why, which the hand-act log keeps
Why string `json:"why"`
}
// SnapshotRemoveAnswer is what snapshot-remove answers.
type SnapshotRemoveAnswer struct {
// accepted: the act's id
Accepted string `json:"accepted,omitempty"`
// busy: the id of the act that runs; it keeps no queue
Busy string `json:"busy,omitempty"`
// why not; set alone
Error string `json:"error,omitempty"`
}
// CreatedEvent is the body of the event created.
type CreatedEvent = Said
@@ -391,5 +494,20 @@ type RecreatedEvent = Said
// DroppedEvent is the body of the event dropped.
type DroppedEvent = Said
// SnapshotRestoredEvent is the body of the event snapshot-restored.
type SnapshotRestoredEvent struct {
Act string `json:"act"`
// when failed
Error string `json:"error,omitempty"`
Outcome string `json:"outcome"`
Request string `json:"request"`
}
// The values of SnapshotRestoredEvent's outcome.
const (
SnapshotRestoredEventOutcomeDone = "done"
SnapshotRestoredEventOutcomeFailed = "failed"
)
// BusStateForm is the form of the provision bus-state.
type BusStateForm = Binding
+34
View File
@@ -37,6 +37,8 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v RecreatedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-broker\\.event\\.recreated$")},
{name: "dropped on the seat's subject", subject: "mesh.seat.mesh-broker.event.dropped", given: "{\"asked\":{\"max-mib\":64},\"bus-name\":\"mesh-knowledge_ledger\",\"fill\":{\"bytes\":2048,\"cap\":67108864,\"count\":10},\"held\":{\"max-mib\":64},\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"storage-type\":\"ledger\",\"template\":\"ledger\",\"why\":\"the bus refused it\"}", wire: "{\"asked\":{\"max-mib\":64},\"bus-name\":\"mesh-knowledge_ledger\",\"fill\":{\"bytes\":2048,\"cap\":67108864,\"count\":10},\"held\":{\"max-mib\":64},\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"storage-type\":\"ledger\",\"template\":\"ledger\",\"why\":\"the bus refused it\"}",
decode: func(b []byte) (any, error) { var v DroppedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-broker\\.event\\.dropped$")},
{name: "snapshot-restored is said under its request and act", subject: "mesh.seat.mesh-broker.event.snapshot-restored.r-1.a-20261111t100000", given: "{\"act\":\"a-20261111t100000\",\"error\":\"names live\",\"outcome\":\"failed\",\"request\":\"r-1\"}", wire: "{\"act\":\"a-20261111t100000\",\"error\":\"names live\",\"outcome\":\"failed\",\"request\":\"r-1\"}",
decode: func(b []byte) (any, error) { var v SnapshotRestoredEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-broker\\.event\\.snapshot-restored\\.[^.*> ]+\\.[^.*> ]+$")},
{name: "create one entry", subject: "", given: "{\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"options\":{\"max-mib\":64},\"storage-type\":\"ledger\",\"template\":\"ledger\"}", wire: "{\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"options\":{\"max-mib\":64},\"storage-type\":\"ledger\",\"template\":\"ledger\"}",
decode: func(b []byte) (any, error) { var v CreateInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "drop on the operator's warrant", subject: "", given: "{\"local-name\":\"old\",\"module\":\"mesh-knowledge\",\"warrant\":\"w-1\",\"why\":\"the operator approved the drop\"}", wire: "{\"local-name\":\"old\",\"module\":\"mesh-knowledge\",\"warrant\":\"w-1\",\"why\":\"the operator approved the drop\"}",
@@ -49,6 +51,38 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v ListAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "list answers a sum with no limit, which is unlimited", subject: "", given: "{\"caps\":{\"sum-mib\":64},\"entries\":[]}", wire: "{\"caps\":{\"sum-mib\":64},\"entries\":[]}",
decode: func(b []byte) (any, error) { var v ListAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "snapshot-get asks a snapshot by its request", subject: "", given: "{\"call\":\"0123456789abcdef0123456789abcdef\",\"request\":\"r-1\"}", wire: "{\"call\":\"0123456789abcdef0123456789abcdef\",\"request\":\"r-1\"}",
decode: func(b []byte) (any, error) { var v SnapshotGetInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "snapshot-get answers the fields and the chunks", subject: "", given: "{\"at\":\"2026-11-11T10:00:00Z\",\"chunks\":2,\"digest\":\"sha256:00\",\"local\":\"ledger\",\"module\":\"mesh-knowledge\",\"request\":\"r-1\",\"size\":1048576,\"stream\":\"mesh-knowledge_ledger\"}", wire: "{\"at\":\"2026-11-11T10:00:00Z\",\"chunks\":2,\"digest\":\"sha256:00\",\"local\":\"ledger\",\"module\":\"mesh-knowledge\",\"request\":\"r-1\",\"size\":1048576,\"stream\":\"mesh-knowledge_ledger\"}",
decode: func(b []byte) (any, error) { var v SnapshotGetAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "snapshot-get answers a protected snapshot refused", subject: "", given: "{\"error\":\"snapshot protected\"}", wire: "{\"error\":\"snapshot protected\"}",
decode: func(b []byte) (any, error) { var v SnapshotGetAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "snapshot-restore asks a verify", subject: "", given: "{\"request\":\"r-1\",\"verify\":true,\"why\":\"the file is read before the live data is set aside\"}", wire: "{\"request\":\"r-1\",\"verify\":true,\"why\":\"the file is read before the live data is set aside\"}",
decode: func(b []byte) (any, error) { var v SnapshotRestoreInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "snapshot-restore answers accepted with the act", subject: "", given: "{\"accepted\":\"a-20261111t100000\"}", wire: "{\"accepted\":\"a-20261111t100000\"}",
decode: func(b []byte) (any, error) { var v SnapshotRestoreAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "snapshot-restore answers busy with the act that runs", subject: "", given: "{\"busy\":\"a-20261111t095900\"}", wire: "{\"busy\":\"a-20261111t095900\"}",
decode: func(b []byte) (any, error) { var v SnapshotRestoreAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "snapshot-restore answers names live", subject: "", given: "{\"error\":\"names live\"}", wire: "{\"error\":\"names live\"}",
decode: func(b []byte) (any, error) { var v SnapshotRestoreAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "snapshot-restore-cancel names the act", subject: "", given: "{\"act\":\"a-20261111t100000\",\"why\":\"the restore passed its bound\"}", wire: "{\"act\":\"a-20261111t100000\",\"why\":\"the restore passed its bound\"}",
decode: func(b []byte) (any, error) {
var v SnapshotRestoreCancelInput
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "snapshot-restore-cancel answers accepted", subject: "", given: "{\"accepted\":\"a-20261111t100000\"}", wire: "{\"accepted\":\"a-20261111t100000\"}",
decode: func(b []byte) (any, error) {
var v SnapshotRestoreCancelAnswer
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "snapshot-remove names one snapshot", subject: "", given: "{\"request\":\"r-1\",\"why\":\"the data is restored\"}", wire: "{\"request\":\"r-1\",\"why\":\"the data is restored\"}",
decode: func(b []byte) (any, error) { var v SnapshotRemoveInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "snapshot-remove names every expired one", subject: "", given: "{\"expired\":true,\"why\":\"the days are past\"}", wire: "{\"expired\":true,\"why\":\"the days are past\"}",
decode: func(b []byte) (any, error) { var v SnapshotRemoveInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "snapshot-remove answers accepted", subject: "", given: "{\"accepted\":\"a-20261111t100000\"}", wire: "{\"accepted\":\"a-20261111t100000\"}",
decode: func(b []byte) (any, error) { var v SnapshotRemoveAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
}
for _, c := range cases {
v, err := c.decode([]byte(c.given))
+11
View File
@@ -265,5 +265,16 @@
},
"why": "the bus refused it"
}
},
{
"name": "snapshot-restored is said under its request and act",
"of": "event:snapshot-restored",
"subject": "mesh.seat.mesh-broker.event.snapshot-restored.r-1.a-20261111t100000",
"given": {
"request": "r-1",
"act": "a-20261111t100000",
"outcome": "failed",
"error": "names live"
}
}
]
+97
View File
@@ -136,5 +136,102 @@
"sum-mib": 64
}
}
},
{
"name": "snapshot-get asks a snapshot by its request",
"of": "verb:snapshot-get.input",
"given": {
"request": "r-1",
"call": "0123456789abcdef0123456789abcdef"
}
},
{
"name": "snapshot-get answers the fields and the chunks",
"of": "verb:snapshot-get.answer",
"given": {
"request": "r-1",
"module": "mesh-knowledge",
"local": "ledger",
"stream": "mesh-knowledge_ledger",
"size": 1048576,
"digest": "sha256:00",
"at": "2026-11-11T10:00:00Z",
"chunks": 2
}
},
{
"name": "snapshot-get answers a protected snapshot refused",
"of": "verb:snapshot-get.answer",
"given": {
"error": "snapshot protected"
}
},
{
"name": "snapshot-restore asks a verify",
"of": "verb:snapshot-restore.input",
"given": {
"request": "r-1",
"verify": true,
"why": "the file is read before the live data is set aside"
}
},
{
"name": "snapshot-restore answers accepted with the act",
"of": "verb:snapshot-restore.answer",
"given": {
"accepted": "a-20261111t100000"
}
},
{
"name": "snapshot-restore answers busy with the act that runs",
"of": "verb:snapshot-restore.answer",
"given": {
"busy": "a-20261111t095900"
}
},
{
"name": "snapshot-restore answers names live",
"of": "verb:snapshot-restore.answer",
"given": {
"error": "names live"
}
},
{
"name": "snapshot-restore-cancel names the act",
"of": "verb:snapshot-restore-cancel.input",
"given": {
"act": "a-20261111t100000",
"why": "the restore passed its bound"
}
},
{
"name": "snapshot-restore-cancel answers accepted",
"of": "verb:snapshot-restore-cancel.answer",
"given": {
"accepted": "a-20261111t100000"
}
},
{
"name": "snapshot-remove names one snapshot",
"of": "verb:snapshot-remove.input",
"given": {
"request": "r-1",
"why": "the data is restored"
}
},
{
"name": "snapshot-remove names every expired one",
"of": "verb:snapshot-remove.input",
"given": {
"expired": true,
"why": "the days are past"
}
},
{
"name": "snapshot-remove answers accepted",
"of": "verb:snapshot-remove.answer",
"given": {
"accepted": "a-20261111t100000"
}
}
]
+244
View File
@@ -209,6 +209,214 @@
},
"optional": true,
"class": "warrant"
},
{
"name": "snapshot-get",
"description": "Send the stream snapshot the bus module took before a drop or recreate: its fields, then the file in chunks of at most 512 KiB on the chunk subject of the call, each acknowledged by the caller on the ack subject within 30 seconds. A caller granted no chunk subjects is answered the fields alone, with chunks 0. Refuses snapshot damaged, snapshot missing, snapshot protected and snapshot taken before milestone G (design 47 G 681).",
"by-caller": true,
"chunks": true,
"class": "read",
"input": {
"type": "object",
"properties": {
"request": {
"type": "string",
"description": "the snapshot's request: the id of the request the keeper took it for, in its state requests",
"minLength": 1
},
"call": {
"type": "string",
"description": "128 random bits the caller chooses: the subject token of this send's chunks and acknowledgements",
"minLength": 1
}
},
"required": [
"request",
"call"
],
"additionalProperties": false
},
"answer": {
"type": "object",
"properties": {
"request": {
"type": "string"
},
"module": {
"type": "string"
},
"local": {
"type": "string",
"description": "the entry's local name"
},
"stream": {
"type": "string",
"description": "the stream's name on the bus"
},
"size": {
"type": "integer",
"minimum": 0
},
"digest": {
"type": "string",
"description": "sha256: of the file's bytes"
},
"at": {
"type": "string",
"format": "date-time",
"description": "when the snapshot was taken, RFC 3339"
},
"chunks": {
"type": "integer",
"minimum": 0,
"description": "how many chunks are sent; 0 when the caller is granted no chunk subjects"
},
"error": {
"type": "string",
"description": "why not: snapshot damaged, snapshot missing, snapshot protected or snapshot taken before milestone G; set alone"
}
}
},
"optional": true
},
{
"name": "snapshot-restore",
"description": "Restore in place the snapshot of a protected stream the bus module took before a drop or recreate, under the stream's own name: with verify true it only checks the file against its recorded digest and restores nothing; it refuses names live while a live object of the stream's name exists. Answers accepted, busy or error at once; the outcome comes on the event snapshot-restored (design 47 G 681).",
"by-caller": true,
"class": "act",
"input": {
"type": "object",
"properties": {
"request": {
"type": "string",
"description": "the snapshot's request: the id of the request the keeper took it for, in its state requests",
"minLength": 1
},
"verify": {
"type": "boolean",
"description": "check the file against its digest and restore nothing"
},
"why": {
"type": "string",
"description": "why, which the hand-act log keeps"
}
},
"required": [
"request",
"why"
],
"additionalProperties": false
},
"answer": {
"type": "object",
"description": "the act accepted, or busy with the act that runs, or the error; exactly one of the three is set (design 47 G 681, 691, A-44)",
"properties": {
"accepted": {
"type": "string",
"description": "accepted: the act's id"
},
"busy": {
"type": "string",
"description": "busy: the id of the act that runs; it keeps no queue"
},
"error": {
"type": "string",
"description": "why not; set alone"
}
}
},
"optional": true
},
{
"name": "snapshot-restore-cancel",
"description": "Cancel a running restore: it removes the keeper's own partial stream, says snapshot-restored with outcome failed under that act and answers accepted, or answers error when that act has ended (design 47 G 681).",
"by-caller": true,
"class": "act",
"input": {
"type": "object",
"properties": {
"act": {
"type": "string",
"description": "the restore's act id",
"minLength": 1
},
"why": {
"type": "string",
"description": "why, which the hand-act log keeps"
}
},
"required": [
"act",
"why"
],
"additionalProperties": false
},
"answer": {
"type": "object",
"description": "the act cancelled, or busy with the act that runs, or the error; exactly one of the three is set (design 47 G 681, 691, A-44)",
"properties": {
"accepted": {
"type": "string",
"description": "accepted: the act's id"
},
"busy": {
"type": "string",
"description": "busy: the id of the act that runs; it keeps no queue"
},
"error": {
"type": "string",
"description": "why not; set alone"
}
}
},
"optional": true
},
{
"name": "snapshot-remove",
"description": "Remove one snapshot and its record now, or every expired one, written in the hand-act log first; a snapshot of before milestone G only by request. Answers accepted, busy or error (design 47 G 681), A-44.",
"by-caller": true,
"class": "act",
"input": {
"type": "object",
"properties": {
"request": {
"type": "string",
"description": "the snapshot's request; or expired true, not both",
"minLength": 1
},
"expired": {
"type": "boolean",
"description": "true: every snapshot past snapshot-keep-days"
},
"why": {
"type": "string",
"description": "why, which the hand-act log keeps"
}
},
"required": [
"why"
],
"additionalProperties": false
},
"answer": {
"type": "object",
"description": "the act accepted, or busy with the act that runs, or the error; exactly one of the three is set (design 47 G 681, 691, A-44)",
"properties": {
"accepted": {
"type": "string",
"description": "accepted: the act's id"
},
"busy": {
"type": "string",
"description": "busy: the id of the act that runs; it keeps no queue"
},
"error": {
"type": "string",
"description": "why not; set alone"
}
}
},
"optional": true
}
],
"events": [
@@ -265,6 +473,42 @@
"body": {
"$ref": "#/defs/Said"
}
},
{
"name": "snapshot-restored",
"subject": "snapshot-restored.<request>.<act>",
"keep": {
"max-age-days": 90,
"last-per-subject": true
},
"body": {
"type": "object",
"description": "how one restore in place of a protected snapshot ended, under the act it was answered accepted with, so a retried restore is told apart from an earlier one (design 47 G 681)",
"properties": {
"request": {
"type": "string"
},
"act": {
"type": "string"
},
"outcome": {
"type": "string",
"enum": [
"done",
"failed"
]
},
"error": {
"type": "string",
"description": "when failed"
}
},
"required": [
"request",
"act",
"outcome"
]
}
}
],
"family": {
+105
View File
@@ -13,6 +13,10 @@ export declare const verbs: {
readonly apply: "apply";
readonly recreate: "recreate";
readonly drop: "drop";
readonly snapshotGet: "snapshot-get";
readonly snapshotRestore: "snapshot-restore";
readonly snapshotRestoreCancel: "snapshot-restore-cancel";
readonly snapshotRemove: "snapshot-remove";
};
export declare const events: {
@@ -25,6 +29,7 @@ export declare const events: {
readonly orphaned: "orphaned";
readonly recreated: "recreated";
readonly dropped: "dropped";
readonly snapshotRestored: "snapshot-restored";
};
export declare const family: { readonly name: "mesh-broker.events"; readonly maxAgeDays: 7 };
@@ -47,6 +52,12 @@ export declare const recreatedSubject: "mesh.seat.mesh-broker.event.recreated";
export declare const droppedSubject: "mesh.seat.mesh-broker.event.dropped";
export declare const snapshotRestoredStream: "SEAT_mesh-broker_snapshot-restored";
export declare function snapshotRestoredSubject(request: string, act: string): string;
export declare const snapshotRestoredSubjectAll: "mesh.seat.mesh-broker.event.snapshot-restored.*.*";
/** the binding a module receives in its membership for one entry (ADR 0595 §1, §7): the names on the bus of the entry's objects, one form in the events, in list, show and orphans, and in the membership */
export interface Binding {
/** a key-value bucket's name */
@@ -268,6 +279,91 @@ export interface DropAnswer {
"snapshot"?: string;
}
/** is what snapshot-get takes. */
export interface SnapshotGetInput {
/** 128 random bits the caller chooses: the subject token of this send's chunks and acknowledgements */
"call": string;
/** the snapshot's request: the id of the request the keeper took it for, in its state requests */
"request": string;
}
/** is what snapshot-get answers. */
export interface SnapshotGetAnswer {
/** when the snapshot was taken, RFC 3339 */
"at"?: string;
/** how many chunks are sent; 0 when the caller is granted no chunk subjects */
"chunks"?: number;
/** sha256: of the file's bytes */
"digest"?: string;
/** why not: snapshot damaged, snapshot missing, snapshot protected or snapshot taken before milestone G; set alone */
"error"?: string;
/** the entry's local name */
"local"?: string;
"module"?: string;
"request"?: string;
"size"?: number;
/** the stream's name on the bus */
"stream"?: string;
}
/** is what snapshot-restore takes. */
export interface SnapshotRestoreInput {
/** the snapshot's request: the id of the request the keeper took it for, in its state requests */
"request": string;
/** check the file against its digest and restore nothing */
"verify"?: boolean;
/** why, which the hand-act log keeps */
"why": string;
}
/** is what snapshot-restore answers. */
export interface SnapshotRestoreAnswer {
/** accepted: the act's id */
"accepted"?: string;
/** busy: the id of the act that runs; it keeps no queue */
"busy"?: string;
/** why not; set alone */
"error"?: string;
}
/** is what snapshot-restore-cancel takes. */
export interface SnapshotRestoreCancelInput {
/** the restore's act id */
"act": string;
/** why, which the hand-act log keeps */
"why": string;
}
/** is what snapshot-restore-cancel answers. */
export interface SnapshotRestoreCancelAnswer {
/** accepted: the act's id */
"accepted"?: string;
/** busy: the id of the act that runs; it keeps no queue */
"busy"?: string;
/** why not; set alone */
"error"?: string;
}
/** is what snapshot-remove takes. */
export interface SnapshotRemoveInput {
/** true: every snapshot past snapshot-keep-days */
"expired"?: boolean;
/** the snapshot's request; or expired true, not both */
"request"?: string;
/** why, which the hand-act log keeps */
"why": string;
}
/** is what snapshot-remove answers. */
export interface SnapshotRemoveAnswer {
/** accepted: the act's id */
"accepted"?: string;
/** busy: the id of the act that runs; it keeps no queue */
"busy"?: string;
/** why not; set alone */
"error"?: string;
}
/** is the body of the event created. */
export type CreatedEvent = Said;
@@ -295,6 +391,15 @@ export type RecreatedEvent = Said;
/** is the body of the event dropped. */
export type DroppedEvent = Said;
/** is the body of the event snapshot-restored. */
export interface SnapshotRestoredEvent {
"act": string;
/** when failed */
"error"?: string;
"outcome": "done" | "failed";
"request": string;
}
/** is the form of the provision bus-state. */
export type BusStateForm = Binding;
+13
View File
@@ -13,6 +13,10 @@ export const verbs = {
apply: "apply",
recreate: "recreate",
drop: "drop",
snapshotGet: "snapshot-get",
snapshotRestore: "snapshot-restore",
snapshotRestoreCancel: "snapshot-restore-cancel",
snapshotRemove: "snapshot-remove",
};
export const events = {
@@ -25,6 +29,7 @@ export const events = {
orphaned: "orphaned",
recreated: "recreated",
dropped: "dropped",
snapshotRestored: "snapshot-restored",
};
export const family = { name: "mesh-broker.events", maxAgeDays: 7 };
@@ -47,3 +52,11 @@ export const recreatedSubject = "mesh.seat.mesh-broker.event.recreated";
export const droppedSubject = "mesh.seat.mesh-broker.event.dropped";
export const snapshotRestoredStream = "SEAT_mesh-broker_snapshot-restored";
export function snapshotRestoredSubject(request, act) {
return "mesh.seat.mesh-broker.event.snapshot-restored." + request + "." + act;
}
export const snapshotRestoredSubjectAll = "mesh.seat.mesh-broker.event.snapshot-restored.*.*";