Run the merge queue on a state-driven coordinator
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
package agents
|
||||
|
||||
import (
|
||||
"context"
|
||||
"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() {
|
||||
finalizing := map[string]bool{}
|
||||
for {
|
||||
select {
|
||||
case <-m.watchStop:
|
||||
return
|
||||
case <-m.pokes:
|
||||
m.coordinateMerges(context.Background(), finalizing)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) coordinateMerges(ctx context.Context, finalizing map[string]bool) {
|
||||
work, err := m.store.CoordinateMerges(ctx)
|
||||
if err != nil {
|
||||
slog.Error("coordinate merges", "err", err)
|
||||
return
|
||||
}
|
||||
for _, id := range work.Abandoned {
|
||||
slog.Info("merge turn ended unfinished", "task", id)
|
||||
m.fileError(ctx, id, abandonedMergeText)
|
||||
m.deliverIdle(ctx, id)
|
||||
}
|
||||
for _, c := range work.Start {
|
||||
m.startClaimedMerge(ctx, c)
|
||||
}
|
||||
current := map[string]bool{}
|
||||
for _, f := range work.Finalize {
|
||||
current[f.Task.Id] = true
|
||||
if finalizing[f.Task.Id] {
|
||||
continue
|
||||
}
|
||||
finalizing[f.Task.Id] = true
|
||||
go m.finalizeMerge(f)
|
||||
}
|
||||
for id := range finalizing {
|
||||
if !current[id] {
|
||||
delete(finalizing, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user