Move lead delivery and the Merge & continue hold onto the coordinator
This commit is contained in:
@@ -55,7 +55,11 @@ func (m *Manager) mergeToMain(ctx context.Context, l *live, raw json.RawMessage)
|
||||
return "", err
|
||||
}
|
||||
login := sess.CreatedBy
|
||||
if by := m.landingBy(l.taskID, l.id); by != "" {
|
||||
by, err := m.store.LandingBy(ctx, l.taskID, l.id)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if by != "" {
|
||||
login = by
|
||||
}
|
||||
user, err := m.store.GetUser(ctx, login)
|
||||
@@ -187,29 +191,16 @@ func (m *Manager) MergeToMain(ctx context.Context, task api.Task, project api.Pr
|
||||
unlock := m.lockDelivery(sess.Id)
|
||||
defer unlock()
|
||||
|
||||
m.mu.Lock()
|
||||
holder := m.landing[task.Id]
|
||||
if holder.session == "" {
|
||||
m.landing[task.Id] = landing{session: sess.Id, login: user.Login}
|
||||
}
|
||||
m.mu.Unlock()
|
||||
if holder.session != "" {
|
||||
return api.Task{}, fmt.Errorf("%w: task %s is already merging and continuing", ErrConflict, task.Id)
|
||||
}
|
||||
sessions, err := m.store.ListSessions(ctx, task.Id)
|
||||
if err == nil {
|
||||
for _, s := range sessions {
|
||||
if s.Role == api.Implementer && s.State == api.AgentSessionStateRunning {
|
||||
err = fmt.Errorf("%w: an agent on this task is mid-turn; merge when they're all idle", ErrConflict)
|
||||
}
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
m.clearMergeAfterReview(ctx, task.Id)
|
||||
_, err = m.Send(ctx, sess.Id, "byre", landPrompt(project.DefaultBranch, title), "", "", "")
|
||||
err = m.store.StartLanding(ctx, task.Id, sess.Id, user.Login)
|
||||
if errors.Is(err, store.ErrStateChanged) {
|
||||
return api.Task{}, fmt.Errorf("%w: %w", ErrConflict, err)
|
||||
}
|
||||
if err != nil {
|
||||
m.endLanding(task.Id, sess.Id)
|
||||
return api.Task{}, err
|
||||
}
|
||||
m.clearMergeAfterReview(ctx, task.Id)
|
||||
_, err = m.launch(ctx, sess, task, "byre", landPrompt(project.DefaultBranch, title), "", "", nil)
|
||||
if err != nil {
|
||||
return api.Task{}, err
|
||||
}
|
||||
|
||||
@@ -220,53 +211,9 @@ func (m *Manager) MergeToMain(ctx context.Context, task api.Task, project api.Pr
|
||||
return m.store.GetTask(ctx, task.Id)
|
||||
}
|
||||
|
||||
type landing struct {
|
||||
session string
|
||||
login string
|
||||
}
|
||||
|
||||
func (m *Manager) heldForLanding(taskID, sessionID string) bool {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
holder := m.landing[taskID].session
|
||||
return holder != "" && holder != sessionID
|
||||
}
|
||||
|
||||
func (m *Manager) landingBy(taskID, sessionID string) string {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if m.landing[taskID].session != sessionID {
|
||||
return ""
|
||||
}
|
||||
return m.landing[taskID].login
|
||||
}
|
||||
|
||||
func (m *Manager) endLanding(taskID, sessionID string) {
|
||||
m.mu.Lock()
|
||||
held := m.landing[taskID].session == sessionID
|
||||
if held {
|
||||
delete(m.landing, taskID)
|
||||
}
|
||||
m.mu.Unlock()
|
||||
if held {
|
||||
go m.releaseTeam(taskID, sessionID)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) releaseTeam(taskID, landingID string) {
|
||||
ctx := context.Background()
|
||||
sessions, err := m.store.ListSessions(ctx, taskID)
|
||||
func (m *Manager) deliverQueuedTurn(sessionID string) {
|
||||
err := m.Deliver(context.Background(), sessionID)
|
||||
if err != nil {
|
||||
slog.Error("list sessions after merge and continue", "task", taskID, "err", err)
|
||||
return
|
||||
}
|
||||
for _, s := range sessions {
|
||||
if s.Id == landingID || s.Role != api.Implementer || s.State != api.AgentSessionStateIdle || m.interrupted(s.Id) {
|
||||
continue
|
||||
}
|
||||
err = m.Deliver(ctx, s.Id)
|
||||
if err != nil {
|
||||
slog.Error("deliver after merge and continue", "session", s.Id, "err", err)
|
||||
}
|
||||
slog.Error("deliver queued message", "session", sessionID, "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user