Skip to content

Quality of Life improvements#267

Open
nytamin wants to merge 5 commits intomainfrom
fix/better-reasons-why
Open

Quality of Life improvements#267
nytamin wants to merge 5 commits intomainfrom
fix/better-reasons-why

Conversation

@nytamin
Copy link
Member

@nytamin nytamin commented Mar 2, 2026

About Me

This pull request is posted on behalf of the NRK.

Type of Contribution

This is a: Bug fix/ Feature / Code improvement

New Behavior

This PR improves the way Package Manager handles expectations in a few ways:

  • If an Expectation has no workers that supports it, it now adds the explanations of all workers to the status of it, rather than just one of them.
  • Improve error handling of testFFExecutable(), the original error message got lost in the thrown Error.
  • Clear state of expectations when Restarting them. This is to force a re-check of Worker support of the expectation.

Status

  • PR is ready to be reviewed.
  • The functionality has been tested by the author.
  • Relevant unit tests has been added / updated.
  • Relevant documentation (code comments, system documentation) has been added / updated.

Quality of Life Improvements

Overview

This PR improves the Package Manager's handling of Expectations, particularly when no workers are available to support them. It changes error reporting to aggregate explanations from all workers instead of only one, preserves original error messages in ffmpeg/executable checks, and ensures Expectation state is cleared on restart so worker support is re-evaluated.

Key Changes

Multi-Worker Explanations

  • Replaced TrackedExpectation.noAvailableWorkersReason: Reason with TrackedExpectation.noAvailableWorkersReasons: Map<WorkerAgentId, Reason> to record per-worker reasons.
  • Updated worker tracking (trackedWorkerAgents.ts) to:
    • populate noAvailableWorkersReasons with { user, tech } per worker for non-support, timeout, and other errors;
    • remove entries for workers that report support.
  • Updated evaluateExpectationStates/new.ts to aggregate per-worker reasons into a user-facing message and a technical message listing all technical reasons plus queried workers, so status explains why no workers support the Expectation.

Improved Error Handling

  • Changed Promise usage in testFFExecutable() (files: shared/packages/api/src/ffmpeg.ts and shared/packages/worker/src/worker/workers/genericWorker/lib/executableDependencyHandler.ts) to await the inner Promise result into a local variable and return it, ensuring the original error message is preserved by existing catch blocks and not lost when rethrowing.

State Clearing on Restart

  • evaluateExpectationStates/restarted.ts now clears trackedExp.queriedWorkers, trackedExp.availableWorkers, and trackedExp.noAvailableWorkersReasons before transitioning the Expectation back to NEW, forcing a fresh re-check of worker support.
  • Added a TODO in the removal error path noting potential future handling for repeated failures.

Types / API

  • Added optional noAssignedWorkerReason?: Reason to ExpectationStateHandlerSession in shared/packages/expectationManager/src/lib/types.ts to carry diagnostics when no worker is assigned.
  • Updated default initialization in getDefaultTrackedExpectation(...) to use an empty Map for noAvailableWorkersReasons.

Impact

  • Improves diagnostics and transparency by reporting aggregated, per-worker reasons when Expectations lack supporting workers.
  • Prevents loss of original error messages during ffmpeg/executable checks.
  • Ensures restarts trigger fresh worker capability evaluation rather than reusing stale state.

Files Touched (high level)

  • shared/packages/api/src/ffmpeg.ts
  • shared/packages/worker/src/worker/workers/genericWorker/lib/executableDependencyHandler.ts
  • shared/packages/expectationManager/src/internalManager/lib/trackedWorkerAgents.ts
  • shared/packages/expectationManager/src/lib/trackedExpectation.ts
  • shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/new.ts
  • shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts
  • shared/packages/expectationManager/src/lib/types.ts

@coderabbitai
Copy link

coderabbitai bot commented Mar 2, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 83f0c2d and 02e88ff.

📒 Files selected for processing (1)
  • shared/packages/expectationManager/src/internalManager/lib/trackedWorkerAgents.ts

Walkthrough

Refactors worker unavailability tracking from a single reason to a per-worker Map, updates logic to collect/aggregate those reasons across state transitions, resets related tracked fields on restart, extends session types for diagnostics, and normalizes promise awaiting in FFmpeg executable checks.

Changes

Cohort / File(s) Summary
Data Structure Refactor
shared/packages/expectationManager/src/lib/trackedExpectation.ts, shared/packages/expectationManager/src/internalManager/lib/trackedWorkerAgents.ts
Replace noAvailableWorkersReason with noAvailableWorkersReasons: Map<WorkerAgentId, Reason>. Initialize as empty Map and populate per-worker reasons; update success, non-support, timeout, and error handling to set/remove entries rather than a single field.
Reason Aggregation & Reporting
shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/new.ts
Aggregate per-worker reasons into a user-facing message (first user reason or "Unknown reason") and a technical message listing all tech reasons plus queried workers; use collected Map values rather than single reason field.
Restart State Reset
shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts
Clear queriedWorkers, availableWorkers, and noAvailableWorkersReasons before re-entering NEW so worker-query data can be repopulated.
Session Type Extension
shared/packages/expectationManager/src/lib/types.ts
Add optional noAssignedWorkerReason?: Reason to ExpectationStateHandlerSession for capturing diagnostic reason when no worker is assigned.
Promise Await Normalization (FFmpeg checks)
shared/packages/api/src/ffmpeg.ts, shared/packages/worker/src/worker/workers/genericWorker/lib/executableDependencyHandler.ts
Change inner Promise handling in testFFExecutable variants to await the result into a local variable and return it (instead of returning the Promise directly), preserving error handling and async semantics.

Sequence Diagram(s)

sequenceDiagram
    participant EvalRunner as EvaluationRunner
    participant Tracker as TrackedExpectation
    participant WorkerAgent as WorkerAgent
    participant State as NEW_State

    EvalRunner->>WorkerAgent: ask doYouSupportExpectation()
    alt Worker supports
        WorkerAgent-->>Tracker: support (remove entry from Map)
    else Worker does not support / error / timeout
        WorkerAgent-->>Tracker: set noAvailableWorkersReasons[workerId] = {user, tech}
    end
    Tracker->>EvalRunner: provide aggregated reasons (user msg, tech list)
    EvalRunner->>State: set status reason fields from aggregated data
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped to each worker, asking why,
Collected reasons, one-by-one, by and by.
Maps in my paws, tech notes in a row,
Awaited the ffmpeg answer slow —
Now diagnostics bloom where questions go.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Quality of Life improvements' is vague and generic, using non-descriptive phrasing that doesn't convey meaningful information about the specific changes in the pull request. Consider using a more specific title that captures the main improvements, such as 'Aggregate worker rejection reasons and improve error handling in expectations' or similar to better reflect the changeset scope.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/better-reasons-why

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts (1)

38-38: Track the restart-failure TODO as an explicit follow-up.

Line 38 sits on an error path; please convert this TODO into a concrete issue/task (retry threshold + fallback transition) to avoid indefinite RESTARTED loops.

I can draft the retry-threshold logic and open an issue template if you want.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts`
at line 38, Convert the inline TODO about repeated restarts into a tracked
follow-up and implement a retry-threshold fallback: create a task/issue
describing “retry threshold + fallback transition for RESTARTED” and then in
restarted.ts introduce a retry counter and constant MAX_RESTART_ATTEMPTS
referenced where RESTARTED handling occurs (e.g., in the function that processes
expectation states in this module), increment the counter each failure, reset it
on successful transition, and when the counter exceeds MAX_RESTART_ATTEMPTS
force a transition to NEW (or another safe fallback) and clear the counter;
ensure the retry counter is persisted or attached to the expectation state so it
survives repeated evaluations and add unit tests exercising the threshold
behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts`:
- Around line 16-21: The code clears trackedExp.queriedWorkers,
trackedExp.availableWorkers, and trackedExp.noAvailableWorkersReasons before
calling manager.workerAgents.assignWorkerToSession which prevents immediate
worker selection because assignWorkerToSession only re-populates
availableWorkers when trackedExp.waitingForWorkerTime !== null; fix by either
(A) resetting trackedExp.waitingForWorkerTime to a non-null value immediately
after clearing those sets so
updateAvailableWorkersForExpectation/determineBestWorkerForExpectation can run
in the same cycle and avoid transitioning to noWorkerAssigned/NEW, or (B) if the
extra iteration is intended, update the inline comment above the clears to
explicitly state that clearing these sets forces a new worker query in the next
cycle and is an intentional behavior to avoid in-cycle reassignments. Ensure
changes reference trackedExp and manager.workerAgents.assignWorkerToSession and
preserve existing state transition logic (determineBestWorkerForExpectation,
noWorkerAssigned, NEW).

In
`@shared/packages/expectationManager/src/internalManager/lib/trackedWorkerAgents.ts`:
- Around line 74-84: The per-worker reason entries set on
trackedExp.noAvailableWorkersReasons are losing error detail and contain a stray
quote in the timeout message; update the two places where you set entries for
workerId (inside the doYouSupportExpectation() error handling) to: fix the typo
in the timeout tech string (remove the extra quote) and preserve full error
diagnostics by converting err to a safe string (e.g., use JSON.stringify(err) or
util.inspect(err) rather than concatenating err to ''), so the tech field
contains actionable error details instead of "[object Object]".

---

Nitpick comments:
In
`@shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts`:
- Line 38: Convert the inline TODO about repeated restarts into a tracked
follow-up and implement a retry-threshold fallback: create a task/issue
describing “retry threshold + fallback transition for RESTARTED” and then in
restarted.ts introduce a retry counter and constant MAX_RESTART_ATTEMPTS
referenced where RESTARTED handling occurs (e.g., in the function that processes
expectation states in this module), increment the counter each failure, reset it
on successful transition, and when the counter exceeds MAX_RESTART_ATTEMPTS
force a transition to NEW (or another safe fallback) and clear the counter;
ensure the retry counter is persisted or attached to the expectation state so it
survives repeated evaluations and add unit tests exercising the threshold
behavior.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1a5fc02 and 83f0c2d.

📒 Files selected for processing (7)
  • shared/packages/api/src/ffmpeg.ts
  • shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/new.ts
  • shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts
  • shared/packages/expectationManager/src/internalManager/lib/trackedWorkerAgents.ts
  • shared/packages/expectationManager/src/lib/trackedExpectation.ts
  • shared/packages/expectationManager/src/lib/types.ts
  • shared/packages/worker/src/worker/workers/genericWorker/lib/executableDependencyHandler.ts

Comment on lines +16 to 21
// Clear this state, so that they will be repopulated in NEW:
trackedExp.queriedWorkers.clear()
trackedExp.availableWorkers.clear()
trackedExp.noAvailableWorkersReasons.clear()

await manager.workerAgents.assignWorkerToSession(trackedExp)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for evaluateExpectationStateRestarted and related restart/restarted patterns
echo "=== Searching for restart-related code ==="
rg -n -C4 --type=ts 'evaluateExpectationStateRestarted|WorkStatusState\.RESTARTED' | head -100

echo -e "\n=== Searching for assignWorkerToSession ==="
rg -n -C6 --type=ts 'assignWorkerToSession\s*\('

echo -e "\n=== Searching for noWorkerAssigned ==="
rg -n -C4 --type=ts 'noWorkerAssigned\s*\('

echo -e "\n=== Searching for waitingForWorkerTime ==="
rg -n -C4 --type=ts 'waitingForWorkerTime\b'

Repository: Sofie-Automation/sofie-package-manager

Length of output: 39882


🏁 Script executed:

#!/bin/bash
# Get the structure of the restarted.ts file to understand the full restart flow
echo "=== Reading restarted.ts file ==="
wc -l shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts
head -50 shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts

Repository: Sofie-Automation/sofie-package-manager

Length of output: 2038


🏁 Script executed:

#!/bin/bash
# Look for assignWorkerToSession implementation to understand what it does
echo "=== Finding assignWorkerToSession implementation ==="
fd -t f -e ts | xargs rg -l 'assignWorkerToSession.*=' | head -5

Repository: Sofie-Automation/sofie-package-manager

Length of output: 134


🏁 Script executed:

#!/bin/bash
# Get the full assignWorkerToSession implementation
sed -n '191,250p' shared/packages/expectationManager/src/internalManager/lib/trackedWorkerAgents.ts

Repository: Sofie-Automation/sofie-package-manager

Length of output: 1833


🏁 Script executed:

#!/bin/bash
# Get the noWorkerAssigned implementation to understand what happens when no worker is available
sed -n '158,175p' shared/packages/expectationManager/src/expectationTracker/lib/trackedExpectationAPI.ts

Repository: Sofie-Automation/sofie-package-manager

Length of output: 795


🏁 Script executed:

#!/bin/bash
# Check if there's any logic that delays assignment based on noWorkerAssignedTime or cleared state
rg -n -C8 'noWorkerAssignedTime' shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts
rg -n -C5 'noWorkerAssignedTime' shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationState.ts

Repository: Sofie-Automation/sofie-package-manager

Length of output: 64


🏁 Script executed:

#!/bin/bash
# Search for any logic that would prevent assignment when state is just cleared
rg -n -B3 -A3 'queriedWorkers\|availableWorkers' shared/packages/expectationManager/src/internalManager/lib/trackedWorkerAgents.ts | head -60

Repository: Sofie-Automation/sofie-package-manager

Length of output: 64


🏁 Script executed:

#!/bin/bash
# Find and examine determineBestWorkerForExpectation
rg -n -A30 'async determineBestWorkerForExpectation' shared/packages/expectationManager/src/internalManager/lib/trackedWorkerAgents.ts

Repository: Sofie-Automation/sofie-package-manager

Length of output: 1333


🏁 Script executed:

#!/bin/bash
# Check if there are any guard conditions that would skip finding a worker after clearing
rg -n -B5 -A15 'updateAvailableWorkersForExpectation' shared/packages/expectationManager/src/internalManager/lib/trackedWorkerAgents.ts | head -80

Repository: Sofie-Automation/sofie-package-manager

Length of output: 1763


🏁 Script executed:

#!/bin/bash
# Look at the flow to see if clearing state would affect the assignment in the same cycle
echo "=== Check if clearing affects waitingForWorkerTime ==="
rg -n 'waitingForWorkerTime' shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts

echo -e "\n=== Full restarted.ts context around assignment ==="
sed -n '14,50p' shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts

Repository: Sofie-Automation/sofie-package-manager

Length of output: 1519


🏁 Script executed:

#!/bin/bash
# Check if clearing state should include resetting waitingForWorkerTime to trigger updateAvailableWorkersForExpectation
echo "=== Check how waitingForWorkerTime is managed in restart ==="
rg -n 'waitingForWorkerTime.*=' shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/ -A2 -B2

echo -e "\n=== Check if noWorkerAssigned sets waitingForWorkerTime ==="
sed -n '158,185p' shared/packages/expectationManager/src/expectationTracker/lib/trackedExpectationAPI.ts

Repository: Sofie-Automation/sofie-package-manager

Length of output: 1244


🏁 Script executed:

#!/bin/bash
# Compare with how other state handlers handle worker assignment
echo "=== Check aborted.ts for comparison ==="
cat shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/aborted.ts

echo -e "\n=== Check new.ts to see if clearing is redundant ==="
cat shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/new.ts

Repository: Sofie-Automation/sofie-package-manager

Length of output: 5704


🏁 Script executed:

#!/bin/bash
# Check the complete noWorkerAssigned flow to understand state transitions
sed -n '158,195p' shared/packages/expectationManager/src/expectationTracker/lib/trackedExpectationAPI.ts

Repository: Sofie-Automation/sofie-package-manager

Length of output: 1427


🏁 Script executed:

#!/bin/bash
# Verify: does clearing state prevent immediate removal in the same cycle?
# Check if the removal would be skipped when no worker is assigned
echo "=== Trace the RESTARTED flow path ==="
echo "1. Clear state in restarted.ts"
echo "2. Call assignWorkerToSession"
echo "3. If availableWorkers is empty and waitingForWorkerTime is null, what happens?"
echo ""
echo "Check if waitingForWorkerTime affects state update:"
rg -n 'waitingForWorkerTime' shared/packages/expectationManager/src/expectationTracker/lib/trackedExpectationAPI.ts -B3 -A3

Repository: Sofie-Automation/sofie-package-manager

Length of output: 313


🏁 Script executed:

#!/bin/bash
# Compare RESTARTED vs ABORTED - why does RESTARTED clear but ABORTED doesn't?
echo "=== ABORTED (without clearing) ==="
sed -n '15,25p' shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/aborted.ts

echo -e "\n=== RESTARTED (with clearing) ==="
sed -n '14,22p' shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts

echo -e "\n=== Check if determineBestWorkerForExpectation needs populated availableWorkers ==="
sed -n '100,120p' shared/packages/expectationManager/src/internalManager/lib/trackedWorkerAgents.ts

Repository: Sofie-Automation/sofie-package-manager

Length of output: 1780


🏁 Script executed:

#!/bin/bash
# Critical: Check if clearing availableWorkers prevents finding workers in determineBestWorkerForExpectation
echo "=== Check the exact flow when availableWorkers is empty ==="
echo "In determineBestWorkerForExpectation, line 112:"
echo "const workerIds = Array.from(trackedExp.availableWorkers.keys())"
echo ""
echo "After clearing, availableWorkers.size = 0"
echo "So workerIds will be empty array"
echo "PromisePool.for([]).process() will not execute any iterations"
echo "bestWorker will be undefined"
echo ""
echo "=== Check updateAvailableWorkersForExpectation trigger ==="
sed -n '215,220p' shared/packages/expectationManager/src/internalManager/lib/trackedWorkerAgents.ts

echo -e "\n=== Does clearing reset waitingForWorkerTime? ==="
grep -n 'waitingForWorkerTime' shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts

Repository: Sofie-Automation/sofie-package-manager

Length of output: 845


🏁 Script executed:

#!/bin/bash
# Check if noWorkerAssigned clears or sets waitingForWorkerTime
sed -n '158,210p' shared/packages/expectationManager/src/expectationTracker/lib/trackedExpectationAPI.ts

Repository: Sofie-Automation/sofie-package-manager

Length of output: 2010


🏁 Script executed:

#!/bin/bash
# Verify: When state transitions to NEW via noWorkerAssigned, is the removal message already sent?
# Check the session state during the transition
rg -n -B5 -A10 'state: ExpectedPackageStatusAPI.WorkStatusState.NEW' shared/packages/expectationManager/src/expectationTracker/lib/trackedExpectationAPI.ts | head -50

Repository: Sofie-Automation/sofie-package-manager

Length of output: 1477


🏁 Script executed:

#!/bin/bash
# Final verification: Does clearing state actually matter, or is it redundant with NEW state?
echo "=== Check if restarted.ts actually needs to clear state ==="
echo "After noWorkerAssigned, state transitions to NEW"
echo "NEW state calls updateAvailableWorkersForExpectation (which repopulates workers)"
echo ""
echo "So the question: Is the clearing necessary at all?"
echo ""
echo "=== Check what state is AFTER clearing and BEFORE calling assignWorkerToSession ==="
echo "State is still RESTARTED when clearing happens"
echo "So if assignWorkerToSession finds a worker, it will:"
echo "1. Assign the worker"
echo "2. Call removeExpectation in RESTARTED state"
echo "3. Transition to NEW state"
echo ""
echo "If no worker found (empty availableWorkers after clear):"
echo "1. noWorkerAssigned() called in RESTARTED state"
echo "2. Transitions to NEW (because availableWorkers.size === 0)"
echo "3. Next cycle: NEW state re-queries workers"
echo ""
echo "=== The concern: Does clearing + empty availableWorkers skip the removal? ==="
sed -n '21,49p' shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts

Repository: Sofie-Automation/sofie-package-manager

Length of output: 1958


🏁 Script executed:

#!/bin/bash
# Check if there's any scenario where workers wouldn't be re-queried
echo "=== If state goes to NEW, will updateAvailableWorkersForExpectation always run? ==="
sed -n '8,35p' shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/new.ts

echo -e "\n=== Conclusion check: Can assignment and removal happen in same cycle after restart? ==="
echo "YES, IF availableWorkers is not empty after clearing"
echo "NO, IF availableWorkers is empty after clearing (because updateAvailableWorkersForExpectation is skipped)"

Repository: Sofie-Automation/sofie-package-manager

Length of output: 1680


Clear worker state before assignment forces an extra iteration in restart flows.

Clearing queriedWorkers, availableWorkers, and noAvailableWorkersReasons (lines 17-19) before calling assignWorkerToSession (line 21) prevents worker assignment in the same cycle. Since assignWorkerToSession only calls updateAvailableWorkersForExpectation when waitingForWorkerTime !== null, the cleared availableWorkers set remains empty, causing determineBestWorkerForExpectation to find no workers. This triggers noWorkerAssigned(), which transitions to NEW state. The removal operation then cannot execute until the next cycle when NEW state re-queries workers.

Consider either:

  1. Resetting waitingForWorkerTime when clearing to trigger immediate worker re-query in the same cycle, or
  2. Accepting the extra iteration as intentional by updating the comment to explain this behavior
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@shared/packages/expectationManager/src/evaluationRunner/evaluateExpectationStates/restarted.ts`
around lines 16 - 21, The code clears trackedExp.queriedWorkers,
trackedExp.availableWorkers, and trackedExp.noAvailableWorkersReasons before
calling manager.workerAgents.assignWorkerToSession which prevents immediate
worker selection because assignWorkerToSession only re-populates
availableWorkers when trackedExp.waitingForWorkerTime !== null; fix by either
(A) resetting trackedExp.waitingForWorkerTime to a non-null value immediately
after clearing those sets so
updateAvailableWorkersForExpectation/determineBestWorkerForExpectation can run
in the same cycle and avoid transitioning to noWorkerAssigned/NEW, or (B) if the
extra iteration is intended, update the inline comment above the clears to
explicitly state that clearing these sets forces a new worker query in the next
cycle and is an intentional behavior to avoid in-cycle reassignments. Ensure
changes reference trackedExp and manager.workerAgents.assignWorkerToSession and
preserve existing state transition logic (determineBestWorkerForExpectation,
noWorkerAssigned, NEW).

@nytamin nytamin changed the title Quality of Lofe improvements Quality of Life improvements Mar 2, 2026
@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 2, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant