diff --git a/cmd/orchestra/main.go b/cmd/orchestra/main.go index cb12adc..874a675 100644 --- a/cmd/orchestra/main.go +++ b/cmd/orchestra/main.go @@ -639,6 +639,23 @@ func main() { ticker := time.NewTicker(time.Second) defer ticker.Stop() for range ticker.C { + // When a coordinator is running, its own Monitor loop (every + // 30s) already calls Store.ExpireLeases and, critically, + // kills the herdr session for whatever it expires (S9: two + // independent expiry loops raced on the same reclaim, and + // since this one runs every second vs. the coordinator's + // 30s, it almost always won — meaning the coordinator's + // ExpireLeases call saw nothing left to expire and its + // session-kill path never ran, silently orphaning panes + // past their lease TTL). Calling ExpireLeases here too would + // just resurrect that race, so leave reclaim to the + // coordinator and only keep retrying pending assignment. + if coordinator != nil { + if _, err := rt.AssignPending(); err != nil { + log.Printf("route expired task: %v", err) + } + continue + } if _, err := s.ExpireLeases(time.Now()); err != nil { log.Printf("expire leases: %v", err) } else if _, err := rt.AssignPending(); err != nil {