84 lines
2.0 KiB
Go
84 lines
2.0 KiB
Go
package agents
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
)
|
|
|
|
const abandonedMergeText = "The Merge turn ended unfinished (interrupted, failed to start, or with no final message), so byre didn't squash or push the task. Merge again to retry."
|
|
|
|
func (m *Manager) poke() {
|
|
select {
|
|
case m.pokes <- struct{}{}:
|
|
default:
|
|
}
|
|
}
|
|
|
|
func (m *Manager) coordinate() {
|
|
started := map[string]bool{}
|
|
for {
|
|
select {
|
|
case <-m.watchStop:
|
|
return
|
|
case <-m.pokes:
|
|
m.coordinatePass(context.Background(), started)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (m *Manager) coordinatePass(ctx context.Context, started map[string]bool) {
|
|
work, err := m.store.Coordinate(ctx)
|
|
if err != nil {
|
|
slog.Error("coordinate", "err", err)
|
|
return
|
|
}
|
|
for _, id := range work.AbandonedMerges {
|
|
slog.Info("merge turn ended unfinished", "task", id)
|
|
m.fileError(ctx, id, abandonedMergeText)
|
|
m.deliverIdle(ctx, id)
|
|
}
|
|
for _, c := range work.StartMerges {
|
|
m.startClaimedMerge(ctx, c)
|
|
}
|
|
for _, id := range work.StartDiscards {
|
|
m.startDiscard(ctx, id)
|
|
}
|
|
for _, r := range work.EndReviewers {
|
|
go m.cleanUpReviewer(r)
|
|
}
|
|
|
|
current := map[string]bool{}
|
|
once := func(key string, run func()) {
|
|
current[key] = true
|
|
if started[key] {
|
|
return
|
|
}
|
|
started[key] = true
|
|
go run()
|
|
}
|
|
for _, f := range work.FinalizeMerges {
|
|
once("merge:"+f.Task.Id, func() { m.finalizeMerge(f) })
|
|
}
|
|
for _, id := range work.FinishDiscards {
|
|
once("discard:"+id, func() { m.finishDiscard(id) })
|
|
}
|
|
for _, r := range work.StartReviews {
|
|
once(fmt.Sprintf("review:%s:%d", r.TaskID, r.N), func() { m.startReviews(r) })
|
|
}
|
|
for _, s := range work.StartStages {
|
|
once(fmt.Sprintf("stage:%s:%d:%s", s.TaskID, s.SnapshotN, s.Stage), func() { m.startReviewStage(s) })
|
|
}
|
|
for _, r := range work.SettleReviews {
|
|
once(fmt.Sprintf("settle:%s:%d", r.TaskID, r.N), func() { m.settleReviews(r) })
|
|
}
|
|
for _, p := range work.ReadyPrompts {
|
|
once("ready:"+p.TaskID, func() { m.promptReady(p) })
|
|
}
|
|
for key := range started {
|
|
if !current[key] {
|
|
delete(started, key)
|
|
}
|
|
}
|
|
}
|