Ask again for a folder that moved, and carry entries left while a disk was away (hq ADR 0325)
The engine names the filesystem a waiting folder is on; a warrant is recorded for that filesystem, and a folder on another is asked about again and not taken there meanwhile. Entries the engine could not take out while their disk was away, stated before a send, do not hold that delivery's gate. mesh-host pinned to d2d9fbbd.
This commit is contained in:
@@ -48,6 +48,9 @@ type Wait struct {
|
||||
// waits for the disk that holds its folder rather than for the operator's word (novox/hq ADR 0325 §7, §9).
|
||||
Access string `json:"access,omitempty"`
|
||||
Disk bool `json:"disk,omitempty"`
|
||||
// Placed is the filesystem the folder is on now, without its path (ADR 0325 §8): a warrant for another does not
|
||||
// answer the wait.
|
||||
Placed string `json:"placed,omitempty"`
|
||||
What string `json:"what"`
|
||||
}
|
||||
|
||||
|
||||
@@ -78,12 +78,14 @@ type TakenFolder struct {
|
||||
Ask string
|
||||
Warrant string
|
||||
Said string
|
||||
// Placed is the filesystem the folder was on when taken, without its path (ADR 0325 §8).
|
||||
Placed string
|
||||
}
|
||||
|
||||
// KeptFolders is every folder taken on a machine, by its clean path.
|
||||
func (i *Inventory) KeptFolders(ctx context.Context, nodeName string) (map[string]TakenFolder, error) {
|
||||
rows, err := i.store.Pool().Query(ctx,
|
||||
`select k.path, k.taken_by, k.ask, k.warrant, k.said from kept_folder k join node n on n.id = k.node
|
||||
`select k.path, k.taken_by, k.ask, k.warrant, k.said, k.placed from kept_folder k join node n on n.id = k.node
|
||||
where n.name = $1`, nodeName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -92,7 +94,7 @@ func (i *Inventory) KeptFolders(ctx context.Context, nodeName string) (map[strin
|
||||
out := map[string]TakenFolder{}
|
||||
for rows.Next() {
|
||||
var t TakenFolder
|
||||
if err := rows.Scan(&t.Path, &t.By, &t.Ask, &t.Warrant, &t.Said); err != nil {
|
||||
if err := rows.Scan(&t.Path, &t.By, &t.Ask, &t.Warrant, &t.Said, &t.Placed); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[t.Path] = t
|
||||
@@ -100,8 +102,9 @@ func (i *Inventory) KeptFolders(ctx context.Context, nodeName string) (map[strin
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
// RecordTaken keeps that a folder was taken on a machine, under the operator's warrant. A take is recorded once:
|
||||
// a second for the same folder keeps the first.
|
||||
// RecordTaken keeps that a folder was taken on a machine, under the operator's warrant. A take is recorded once per
|
||||
// filesystem: a second for the same folder on the same filesystem keeps the first, and one for the folder on another
|
||||
// filesystem (it moved, and the operator was asked again) replaces it.
|
||||
func (i *Inventory) RecordTaken(ctx context.Context, nodeName string, t TakenFolder) error {
|
||||
switch {
|
||||
case !strings.HasPrefix(t.Path, "/"):
|
||||
@@ -114,7 +117,11 @@ func (i *Inventory) RecordTaken(ctx context.Context, nodeName string, t TakenFol
|
||||
return err
|
||||
}
|
||||
_, err = i.store.Pool().Exec(ctx,
|
||||
`insert into kept_folder (node, path, taken_by, ask, warrant, said) values ($1, $2, $3, $4, $5, $6)
|
||||
on conflict (node, path) do nothing`, node.ID, filepath.Clean(t.Path), t.By, t.Ask, t.Warrant, t.Said)
|
||||
`insert into kept_folder (node, path, taken_by, ask, warrant, said, placed) values ($1, $2, $3, $4, $5, $6, $7)
|
||||
on conflict (node, path) do update
|
||||
set taken_at = now(), taken_by = excluded.taken_by, ask = excluded.ask, warrant = excluded.warrant,
|
||||
said = excluded.said, placed = excluded.placed
|
||||
where kept_folder.placed is distinct from excluded.placed`, node.ID, filepath.Clean(t.Path), t.By, t.Ask,
|
||||
t.Warrant, t.Said, t.Placed)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -96,6 +96,18 @@ func TestAFolderIsTakenOnceUnderAWarrant(t *testing.T) {
|
||||
if !has || got.Ask != "c01" || got.By != "the operator" {
|
||||
t.Fatalf("the taken folder reads %+v (%v): the first take, by its clean path", got, has)
|
||||
}
|
||||
// The folder moved to another filesystem and the operator was asked again: the new take replaces the old.
|
||||
if err := inv.RecordTaken(ctx, "ace", TakenFolder{Path: "/storage/media/movies", By: "the operator", Ask: "c03",
|
||||
Warrant: "c03", Placed: "fs-0000000000ff"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
kept, err = inv.KeptFolders(ctx, "ace")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := kept["/storage/media/movies"]; got.Ask != "c03" || got.Placed != "fs-0000000000ff" {
|
||||
t.Fatalf("after a take on another filesystem the folder reads %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
// novox/hq issue 575: a module registered without the access movies, whose newest build on its branch declares it —
|
||||
|
||||
+5
-1
@@ -25,7 +25,7 @@ create table module_identity (
|
||||
-- everything there, and the folder is taken: kept from then on without asking, a module that gains the access
|
||||
-- added with no wait. The row is the record of that act — who approved it, under which warrant — and what tells a
|
||||
-- later module's access that it joins a taken folder (`taken` on the access). The path is the folder as placed,
|
||||
-- clean and absolute.
|
||||
-- clean and absolute. A new warrant for the same folder on another filesystem replaces the row.
|
||||
create table kept_folder (
|
||||
node uuid not null references node (id) on delete cascade,
|
||||
path text not null check (path like '/%'),
|
||||
@@ -36,5 +36,9 @@ create table kept_folder (
|
||||
warrant text not null,
|
||||
-- What the node-engine answered when it started the take.
|
||||
said text not null default '',
|
||||
-- The filesystem the folder was on when it was taken, as the engine names it without a path ("fs-<12 hex>"):
|
||||
-- a wait naming another (the folder moved to another disk) is not answered by this take, and the operator is
|
||||
-- asked again; until the new warrant the folder is not taken there. Empty from an engine that names none.
|
||||
placed text not null default '',
|
||||
primary key (node, path)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user