mesh-hand-acts lists acts from its own log alone and no longer copies: its copy tools answer that the copy is over, with the marker of the copy that was made (the live top-up runs before this delivery). mesh-healers drops the watch of mesh-controller_hand-acts and counts the seat's acts: it asks the seat's `hand-acts` once at its start for the fortnight (new invoke) and hears act-recorded after, an act listed and heard counting once, so a restart does not forget the fortnight. Tests: the two-log listing and the copy table became one listing and one copy-is-over test; the healers' count test lost its controller-bucket helper and gained the seat listing; the integration test now proves the old bucket is not copied. (issue 774, 774/S10) Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
82 lines
3.2 KiB
Go
82 lines
3.2 KiB
Go
package main
|
|
|
|
// The one-time copy of the controller's hand-act log into this seat's log is over (novox/hq research 072 row 26, ADR 0571
|
|
// §13, issue 774). The controller kept every act of its life in its bucket `mesh-controller_hand-acts`; they were copied
|
|
// once into `acts`, each as the controller wrote it, by the earlier builds of this module, which left the marker
|
|
// `controller-hand-acts` of the state `copied`. This module no longer reads that bucket, so the copy cannot run: the
|
|
// tools `hand_acts_copy` and `hand_acts_copied` stay and say so, with the marker's figures when it exists.
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// CopiedState is the state that holds the marker, and CopyKey the marker's key.
|
|
const (
|
|
CopiedState = "copied"
|
|
CopyKey = "controller-hand-acts"
|
|
)
|
|
|
|
// CopyMarker is what the copy leaves behind once it is whole: when, by what, how many acts, and which entries could not
|
|
// be read as acts (copied unchanged all the same, so nothing is lost).
|
|
type CopyMarker struct {
|
|
At time.Time `json:"at"`
|
|
By string `json:"by"`
|
|
Source string `json:"source"`
|
|
Found int `json:"found"`
|
|
Copied int `json:"copied"`
|
|
Already int `json:"already-there"`
|
|
// Unreadable are the keys whose value is not an act; they were copied as they were.
|
|
Unreadable []string `json:"unreadable,omitempty"`
|
|
FirstKey string `json:"first-key,omitempty"`
|
|
LastKey string `json:"last-key,omitempty"`
|
|
}
|
|
|
|
// CopyStatus is what the tools answer: the marker if the copy is whole, and how the two logs stand now.
|
|
type CopyStatus struct {
|
|
Done bool `json:"done"`
|
|
Marker *CopyMarker `json:"marker,omitempty"`
|
|
// Said is a sentence for a person: what this call did or found.
|
|
Said string `json:"said"`
|
|
// New is how many acts this seat's log holds.
|
|
New *int `json:"new-log-entries,omitempty"`
|
|
}
|
|
|
|
// gone is what a call to copy answers.
|
|
const gone = "the controller's hand-act log is no longer read, so nothing can be copied (novox/hq ADR 0571 §13, issue 774); " +
|
|
"the acts copied before are in the log `acts`"
|
|
|
|
// Copy answers that the copy is over: it reads and writes nothing of the controller's. The marker, when the copy once
|
|
// ran to its end, is returned with the answer.
|
|
func (l *Log) Copy(by string, topUp bool) (CopyStatus, error) {
|
|
st, err := l.Copied()
|
|
if err != nil {
|
|
return st, err
|
|
}
|
|
st.Said = gone + "; " + st.Said
|
|
return st, nil
|
|
}
|
|
|
|
// Copied says where the copy ended: the marker with its figures, or that none was left, and how many acts the log holds.
|
|
func (l *Log) Copied() (CopyStatus, error) {
|
|
raw, found, err := l.Store.Get(CopiedState, CopyKey)
|
|
if err != nil {
|
|
return CopyStatus{}, fmt.Errorf("the copy's marker cannot be read: %w", err)
|
|
}
|
|
st := CopyStatus{Said: "no marker of a finished copy is left"}
|
|
if found {
|
|
var m CopyMarker
|
|
if err := json.Unmarshal(raw, &m); err != nil {
|
|
return CopyStatus{}, fmt.Errorf("the copy's marker is not readable: %w", err)
|
|
}
|
|
st = CopyStatus{Done: true, Marker: &m, Said: fmt.Sprintf("copied at %s by %s: %d copied, %d already there, of %d in %s",
|
|
m.At.Format(time.RFC3339), m.By, m.Copied, m.Already, m.Found, m.Source)}
|
|
}
|
|
if f, err := l.Store.Fill(ActsLog); err == nil {
|
|
n := int(f.Entries)
|
|
st.New = &n
|
|
}
|
|
return st, nil
|
|
}
|