95 lines
5.7 KiB
Go
95 lines
5.7 KiB
Go
package index
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-indexer/takein"
|
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
|
)
|
|
|
|
// PendingTools are the indexer's tools of what waits for a take-in (novox/hq ADR 0633 §5): indexer_pending reads the
|
|
// pending state, and indexer_take_in_pending and indexer_drop_pending steer it by an ask in takeins, as indexer_take_in
|
|
// does. pending is the pending state as the tools bundle reads it; ask writes an ask and waits for the indexer's answer.
|
|
func PendingTools(pending Store, ask func(key string, value []byte) (TakeInAsk, error), now func() time.Time) []stdio.Tool {
|
|
str := func(args map[string]any, k string) string { s, _ := args[k].(string); return s }
|
|
hand := func(drop bool) func(map[string]any) (any, error) {
|
|
return func(args map[string]any) (any, error) {
|
|
key, value, err := NewPendingAsk(str(args, "key"), str(args, "why"), stdio.CallerOf(args), drop, now())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
a, err := ask(key, value)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return a.Result, nil
|
|
}
|
|
}
|
|
merge := func(args map[string]any) (any, error) {
|
|
seq, _ := args["sequence"].(float64)
|
|
key, value, err := NewMergeAsk(str(args, "repository"), str(args, "merge"), uint64(seq), str(args, "why"), stdio.CallerOf(args), now())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
a, err := ask(key, value)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return a.Result, nil
|
|
}
|
|
return []stdio.Tool{
|
|
{Name: PendingTool,
|
|
Description: "What waits for a take-in (ADR 0633): merges the indexer holds in its pending state instead of taking them in. " +
|
|
"A revision (what revision, its key its oldest merge's m.<sequence>) waits for the build of the indexer it names " +
|
|
"(waits-for): the running indexer wrote only what building and moving that indexer needs, and the new indexer takes " +
|
|
"it in at its start. A group (what group, key g.<group>) is a delivery group whose members are gathered until the " +
|
|
"forge bridge says its end; a merge in one of its members' repositories waits behind it (behind). Each names its " +
|
|
"merges, since when it waits, the modules it holds back (holds), the merges whose message the forge bridge's stream no " +
|
|
"longer holds (lost: they are not taken in; indexer_drop_pending drops them) and the last take-in event said of it. Empty waits: " +
|
|
"every merge is taken in. The watchman raises take-in-waits past 60 minutes for a revision, 30 for a group; " +
|
|
"indexer_take_in_pending and indexer_drop_pending steer a wait.",
|
|
Input: map[string]any{"type": "object", "properties": map[string]any{}},
|
|
Run: func(map[string]any) (any, error) {
|
|
var unread []string
|
|
entries, err := ReadPending(context.Background(), pending, func(format string, args ...any) {
|
|
unread = append(unread, fmt.Sprintf(format, args...))
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return takein.PendingAnswer{Waits: PendingWaits(entries), Unread: unread}, nil
|
|
}},
|
|
{Name: TakeInPendingTool,
|
|
Description: "Take a wait in by hand with the running indexer and its judge (ADR 0633 §5): the revision under its m. key, " +
|
|
"whatever build of the indexer it names, or a delivery group under its g. key with the members gathered so far. For " +
|
|
"when the named indexer can never run, or a group's end never comes. A hand act: who and why are said in the " +
|
|
"indexer's journal and on the take-in.taken event, which clears take-in-waits. indexer_pending names the keys.",
|
|
Input: map[string]any{"type": "object", "required": []string{"key", "why"}, "properties": map[string]any{
|
|
"key": map[string]any{"type": "string", "description": "the wait's key, m.<sequence> or g.<group>, as indexer_pending names it"},
|
|
"why": map[string]any{"type": "string", "description": "why it is taken in by hand, in plain words"}}},
|
|
Run: hand(false)},
|
|
{Name: DropPendingTool,
|
|
Description: "Drop one pending merge by hand, abandoned because a later merge replaced it (ADR 0633 §5): it is removed from " +
|
|
"the pending state and nothing of it is taken in; what waited with it is worked out again. A hand act: who and why are " +
|
|
"said in the journal and on the take-in.taken event (dropped).",
|
|
Input: map[string]any{"type": "object", "required": []string{"key", "why"}, "properties": map[string]any{
|
|
"key": map[string]any{"type": "string", "description": "the pending merge's key, m.<sequence>, as indexer_pending names its merges' wait"},
|
|
"why": map[string]any{"type": "string", "description": "why it is dropped, in plain words"}}},
|
|
Run: hand(true)},
|
|
{Name: TakeInMergeTool,
|
|
Description: "Take one merge in by hand (ADR 0633 §5, issue 1585): the indexer asks the forge bridge for the merge's merged message " +
|
|
"(bridge_merged_message) and runs it through the take-in as a delivered merged message, so it is held for the " +
|
|
"indexer its revision names or taken in. For a merge the take-in did not take in (indexer_heard names its sequence " +
|
|
"and why). A hand act: who and why are said in the indexer's journal. The bridge's own words answer when it cannot " +
|
|
"build the message (the gate holds no such merge, the forge does not answer).",
|
|
Input: map[string]any{"type": "object", "required": []string{"repository", "merge", "sequence", "why"}, "properties": map[string]any{
|
|
"repository": map[string]any{"type": "string", "description": "the repository, owner/name"},
|
|
"merge": map[string]any{"type": "string", "description": "the merge commit, 40 hex digits"},
|
|
"sequence": map[string]any{"type": "integer", "description": "the merge's sequence on the forge bridge's stream, as indexer_heard names it"},
|
|
"why": map[string]any{"type": "string", "description": "why it is taken in by hand, in plain words"}}},
|
|
Run: merge},
|
|
}
|
|
}
|