Pass snapshot requests intact through the snapshot pipeline

This commit is contained in:
Ian Gulliver
2026-10-23 17:42:18 -07:00
parent 758aa7f893
commit 0d793eed45
2 changed files with 24 additions and 27 deletions
+1 -1
View File
@@ -1376,7 +1376,7 @@ func (m *Manager) turnEnded(ctx context.Context, l *live, res endResult) error {
return err
}
if snapshot && !held {
m.snapshotSoon(liveTarget(l), api.SnapshotTriggerTurnEnd, 0, review, false)
m.snapshotSoon(snapRequest{target: liveTarget(l), trigger: api.SnapshotTriggerTurnEnd, review: review})
}
if end.Discard != store.DiscardNone {
+23 -26
View File
@@ -20,7 +20,6 @@ import (
type snapRequest struct {
target snapTarget
trigger api.SnapshotTrigger
seq int64
review bool
force bool
}
@@ -54,27 +53,27 @@ func (m *Manager) snapStateLocked(taskID string) *snapState {
return st
}
func (m *Manager) snapshotSoon(t snapTarget, trigger api.SnapshotTrigger, seq int64, review, force bool) {
func (m *Manager) snapshotSoon(req snapRequest) {
t := req.target
m.snapMu.Lock()
defer m.snapMu.Unlock()
st := m.snapStateLocked(t.taskID)
if st.closed {
m.dropRequest(t.taskID, &snapRequest{review: review})
m.dropRequest(&req)
return
}
req := &snapRequest{target: t, trigger: trigger, seq: seq, review: review, force: force}
if st.running {
if p := st.pending; p != nil && p.force {
req.force = true
req.trigger = p.trigger
}
m.dropRequest(t.taskID, st.pending)
st.pending = req
m.dropRequest(st.pending)
st.pending = &req
return
}
st.running = true
go m.runSnapshots(st, req)
go m.runSnapshots(st, &req)
}
func (m *Manager) runSnapshots(st *snapState, req *snapRequest) {
@@ -86,15 +85,15 @@ func (m *Manager) runSnapshots(st *snapState, req *snapRequest) {
closed := st.closed
m.snapMu.Unlock()
if !closed {
snap, err := m.takeSnapshot(context.Background(), t, req.trigger, req.seq, req.force, req.review)
snap, err := m.takeSnapshot(context.Background(), *req)
if err != nil {
slog.Error("take snapshot", "task", t.taskID, "trigger", req.trigger, "err", err)
}
if snap == nil {
m.dropRequest(t.taskID, req)
m.dropRequest(req)
}
} else {
m.dropRequest(t.taskID, req)
m.dropRequest(req)
}
st.mu.Unlock()
unlock()
@@ -103,7 +102,7 @@ func (m *Manager) runSnapshots(st *snapState, req *snapRequest) {
req = st.pending
st.pending = nil
if req == nil || st.closed {
m.dropRequest(t.taskID, req)
m.dropRequest(req)
st.running = false
m.snapMu.Unlock()
return
@@ -112,9 +111,9 @@ func (m *Manager) runSnapshots(st *snapState, req *snapRequest) {
}
}
func (m *Manager) dropRequest(taskID string, req *snapRequest) {
func (m *Manager) dropRequest(req *snapRequest) {
if req != nil && req.review {
m.endReviewRequest(taskID)
m.endReviewRequest(req.target.taskID)
}
}
@@ -125,13 +124,11 @@ func (m *Manager) endReviewRequest(taskID string) {
}
}
func (m *Manager) takeSnapshot(ctx context.Context, t snapTarget, trigger api.SnapshotTrigger, seq int64, force, review bool) (*api.Snapshot, error) {
if seq == 0 {
var err error
seq, err = m.store.LastTaskSeq(ctx, t.taskID)
if err != nil {
return nil, err
}
func (m *Manager) takeSnapshot(ctx context.Context, req snapRequest) (*api.Snapshot, error) {
t := req.target
seq, err := m.store.LastTaskSeq(ctx, t.taskID)
if err != nil {
return nil, err
}
tree, err := git.Snapshot(ctx, t.dir)
@@ -147,12 +144,12 @@ func (m *Manager) takeSnapshot(ctx context.Context, t snapTarget, trigger api.Sn
if err != nil && !errors.Is(err, store.ErrNotFound) {
return nil, err
}
if err == nil && reviewed.TreeSha == tree && !force {
if err == nil && reviewed.TreeSha == tree && !req.force {
return nil, nil
}
n := last.N + 1
commit, err := git.CommitSnapshot(ctx, t.dir, tree, git.SnapshotRef(t.taskID, n), fmt.Sprintf("byre snapshot #%d (%s)", n, trigger), git.IdentityEnv(t.gitName, t.gitEmail))
commit, err := git.CommitSnapshot(ctx, t.dir, tree, git.SnapshotRef(t.taskID, n), fmt.Sprintf("byre snapshot #%d (%s)", n, req.trigger), git.IdentityEnv(t.gitName, t.gitEmail))
if err != nil {
return nil, err
}
@@ -165,10 +162,10 @@ func (m *Manager) takeSnapshot(ctx context.Context, t snapTarget, trigger api.Sn
CommitSha: commit,
TreeSha: tree,
EventSeq: seq,
Trigger: trigger,
Trigger: req.trigger,
CreatedAt: time.Now().UTC(),
}
err = m.store.CreateSnapshot(ctx, snap, t.projectID, review)
err = m.store.CreateSnapshot(ctx, snap, t.projectID, req.review)
if err != nil {
return nil, err
}
@@ -215,7 +212,7 @@ func (m *Manager) RequestSnapshot(ctx context.Context, taskID string) error {
if err != nil {
return err
}
m.snapshotSoon(t, api.SnapshotTriggerRequested, 0, true, true)
m.snapshotSoon(snapRequest{target: t, trigger: api.SnapshotTriggerRequested, review: true, force: true})
return nil
}
@@ -256,7 +253,7 @@ func (m *Manager) cutSnapshot(ctx context.Context, t snapTarget, held bool, trig
if closed {
return nil, nil
}
return m.takeSnapshot(ctx, t, trigger, 0, true, false)
return m.takeSnapshot(ctx, snapRequest{target: t, trigger: trigger, force: true})
}
func (m *Manager) takeSnapshotTool(l *live) mcp.Tool {