summaryrefslogtreecommitdiff
path: root/internal/executor/executor.go
diff options
context:
space:
mode:
authorClaudomator Agent <agent@claudomator>2026-03-09 05:02:36 +0000
committerClaudomator Agent <agent@claudomator>2026-03-09 05:02:36 +0000
commit7c7dd2bc352c91963ece06f3176a032ee7ab462f (patch)
treef6d329d095a88c8138d9fb043cdf8106d7585715 /internal/executor/executor.go
parent67b8544b222392d8a01847e3d34559c23fd0cd12 (diff)
executor: fix map leaks in activePerAgent and rateLimited
activePerAgent: delete zero-count entries after decrement so the map doesn't accumulate stale keys for agent types that are no longer active. rateLimited: delete entries whose deadline has passed when reading them (in both the classifier block and the execute() pre-flight), so stale entries are cleaned up on the next check rather than accumulating forever. Both fixes are covered by new regression tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/executor/executor.go')
-rw-r--r--internal/executor/executor.go12
1 files changed, 12 insertions, 0 deletions
diff --git a/internal/executor/executor.go b/internal/executor/executor.go
index 9dd37ae..1c9e667 100644
--- a/internal/executor/executor.go
+++ b/internal/executor/executor.go
@@ -179,6 +179,9 @@ func (p *Pool) executeResume(ctx context.Context, t *task.Task, exec *storage.Ex
p.mu.Lock()
p.active--
p.activePerAgent[agentType]--
+ if p.activePerAgent[agentType] == 0 {
+ delete(p.activePerAgent, agentType)
+ }
p.mu.Unlock()
select {
case p.doneCh <- struct{}{}:
@@ -296,6 +299,9 @@ func (p *Pool) execute(ctx context.Context, t *task.Task) {
now := time.Now()
for agent := range p.runners {
activeTasks[agent] = p.activePerAgent[agent]
+ if deadline, ok := p.rateLimited[agent]; ok && now.After(deadline) {
+ delete(p.rateLimited, agent)
+ }
activeUntil := p.rateLimited[agent]
isLimited := now.Before(activeUntil)
rateLimited[agent] = isLimited
@@ -326,6 +332,9 @@ func (p *Pool) execute(ctx context.Context, t *task.Task) {
}
p.mu.Lock()
+ if deadline, ok := p.rateLimited[agentType]; ok && time.Now().After(deadline) {
+ delete(p.rateLimited, agentType)
+ }
p.activePerAgent[agentType]++
p.mu.Unlock()
@@ -333,6 +342,9 @@ func (p *Pool) execute(ctx context.Context, t *task.Task) {
p.mu.Lock()
p.active--
p.activePerAgent[agentType]--
+ if p.activePerAgent[agentType] == 0 {
+ delete(p.activePerAgent, agentType)
+ }
p.mu.Unlock()
select {
case p.doneCh <- struct{}{}: