Preserve leases needing recovery

This commit is contained in:
kami
2026-07-30 14:37:34 +04:00
parent f6ee0e3060
commit 8174400b1a
12 changed files with 106 additions and 39 deletions
+5 -5
View File
@@ -445,7 +445,7 @@ func (c *Coordinator) Reconcile(ctx context.Context) error {
c.mu.Lock()
for taskID, session := range c.sessions {
t, ok := c.Store.Task(taskID)
if ok && (t.State == domain.StateLeased || t.State == domain.StateBlocked) {
if ok && (t.State == domain.StateLeased || t.State == domain.StateNeedsAttention) {
continue
}
if a, err := c.adapterFor(taskID, session); err == nil {
@@ -589,7 +589,7 @@ func (c *Coordinator) expire(ctx context.Context) ([]domain.Event, error) {
c.loadSessions()
c.mu.Lock()
for taskID, s := range c.sessions {
if t, ok := c.Store.Task(taskID); ok && t.State == domain.StateLeased {
if t, ok := c.Store.Task(taskID); ok && (t.State == domain.StateLeased || t.State == domain.StateNeedsAttention) {
if a, ae := c.adapterFor(taskID, s); ae == nil {
if p, ok := a.(herdr.PaneExit); ok {
if exited, ee := p.PaneExited(ctx, s); ee == nil && exited {
@@ -604,7 +604,7 @@ func (c *Coordinator) expire(ctx context.Context) ([]domain.Event, error) {
var events []domain.Event
var firstErr error
for _, task := range c.Store.Tasks() {
if task.State != domain.StateLeased || task.Lease == nil || task.Lease.Until.After(time.Now()) {
if (task.State != domain.StateLeased && task.State != domain.StateNeedsAttention) || task.Lease == nil || task.Lease.Until.After(time.Now()) {
continue
}
// Stop a local predecessor before making its lease eligible for a
@@ -947,7 +947,7 @@ func (c *Coordinator) Start(ctx context.Context, e domain.Event) error {
}
if err != nil {
// A UI-changing prompt can time out after herdr accepted it. Keep the
// live pane mapped before recording TaskBlocked so a later completion
// live pane mapped before recording TaskNeedsAttention so a later completion
// can reconcile the lifecycle instead of becoming an orphan (B15).
if s.PaneID != "" {
s.HerdrID = p.HarnessID
@@ -1034,7 +1034,7 @@ func (c *Coordinator) block(t domain.Task, reason string) error {
p["expected_version"] = t.Version
b, _ = json.Marshal(p)
}
return c.Store.Append(domain.Event{ID: domain.NewID(), Type: "TaskBlocked", TaskID: t.ID, Version: t.Version + 1, Payload: b, Surface: string(authz.System)})
return c.Store.Append(domain.Event{ID: domain.NewID(), Type: "TaskNeedsAttention", TaskID: t.ID, Version: t.Version + 1, Payload: b, Surface: string(authz.System)})
}
func (c *Coordinator) Session(taskID string) (herdr.Session, bool) {