Files
mesh-delivery/modules/mesh-delivery-builder/internal/versions/heard.go
T
jschoubben 6b3a679151 DLV-B5: builder_publish_again, builder_floor_again, builder_tag, builder_tag_asks and builder_untag, with the state tag-asks
A holder that failed leaves a version to publish again by hand: said numbered again while the build is held, built
again under the same number when its file is gone, numbered anew after a published; refused for other bytes. The
floor is asked again by hand; a branch's tagged versions are removed through each seat's remove, per repository.

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
2026-11-04 12:30:20 +01:00

64 lines
2.0 KiB
Go

package versions
import (
"context"
"fmt"
)
// The registry seats' events the builder hears on its durable consumer of each `<seat>.events` (design 51 *How a
// publish ends*, DLV-B4).
const (
HeardPublished = "published"
HeardRefused = "refused"
HeardRemoved = "removed"
)
// Outcome is the body of a registry seat's published, refused and removed (mesh-contracts parts/registry Outcome), the
// fields the builder reads.
type Outcome struct {
Name string `json:"name"`
Version string `json:"version,omitempty"`
Digest string `json:"digest"`
Kind string `json:"kind"`
Holder string `json:"holder"`
Reason string `json:"reason,omitempty"`
}
// Heard takes one seat event in: a numbered version's entry turns published (with its digest when it held none),
// refused with the holder's reason, or removed with its reason and the event's id; a by-digest publish (no version)
// marks nothing. It answers the names waiting on their floor that the event wakes: a `published` says the seat
// answers (design 51 *The floor*).
func (n *Numberer) Heard(ctx context.Context, seat, event, id string, o Outcome) ([]string, error) {
var wake []string
if event == HeardPublished && n.Waits != nil {
wake = n.Waits.Wake(WakePublished, seat, "", "")
}
if o.Version == "" {
return wake, nil
}
var change func(*Entry)
switch event {
case HeardPublished:
change = func(e *Entry) {
e.State, e.Reason = Published, ""
if e.Digest == "" {
e.Digest = o.Digest
}
}
case HeardRefused:
change = func(e *Entry) {
if e.State != Published {
e.State, e.Reason, e.RefusedDigest = Refused, o.Reason, o.Digest
}
}
case HeardRemoved:
change = func(e *Entry) { e.State, e.Reason, e.RemovedBy = Removed, o.Reason, id }
default:
return wake, fmt.Errorf("%s says %q, which the builder does not hear", seat, event)
}
if _, err := n.Versions.Mark(ctx, o.Name, o.Version, change); err != nil {
return wake, fmt.Errorf("%s's %s of %s@%s: %w", seat, event, o.Name, o.Version, err)
}
return wake, nil
}