feat: rotate sessions on occupancy threshold
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Worktrees interface {
|
||||
@@ -68,6 +69,61 @@ type Coordinator struct {
|
||||
sessions map[string]herdr.Session
|
||||
}
|
||||
|
||||
// Monitor performs conservative hard-threshold rotation. The adapter owns
|
||||
// the handoff creation; the coordinator only publishes its content address
|
||||
// and frees the lease for pickup by the router.
|
||||
func (c *Coordinator) Monitor(ctx context.Context, hard float64, interval time.Duration) error {
|
||||
if interval <= 0 {
|
||||
interval = 30 * time.Second
|
||||
}
|
||||
t := time.NewTicker(interval)
|
||||
defer t.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-t.C:
|
||||
c.rotate(ctx, hard)
|
||||
}
|
||||
}
|
||||
}
|
||||
func (c *Coordinator) rotate(ctx context.Context, hard float64) {
|
||||
c.mu.Lock()
|
||||
sessions := make(map[string]herdr.Session, len(c.sessions))
|
||||
for id, s := range c.sessions {
|
||||
sessions[id] = s
|
||||
}
|
||||
c.mu.Unlock()
|
||||
for taskID, session := range sessions {
|
||||
task, ok := c.Store.Task(taskID)
|
||||
if !ok || task.State != domain.StateLeased {
|
||||
continue
|
||||
}
|
||||
a, err := c.Adapters.Adapter(session.Harness)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
occupancy, err := a.Occupancy(session)
|
||||
if err != nil || occupancy < hard {
|
||||
continue
|
||||
}
|
||||
ref, err := a.Release(ctx, session)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if ref == "" {
|
||||
continue
|
||||
}
|
||||
b, _ := json.Marshal(map[string]string{"handoff_ref": ref, "reason": "threshold"})
|
||||
e := domain.Event{ID: domain.NewID(), Type: "TaskReleased", TaskID: taskID, Version: task.Version + 1, Payload: b}
|
||||
if c.Store.Append(e) == nil {
|
||||
c.mu.Lock()
|
||||
delete(c.sessions, taskID)
|
||||
c.mu.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Coordinator) Start(ctx context.Context, e domain.Event) error {
|
||||
if e.Type != "TaskLeased" {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user