Skip to content

tasklist: start every unblocked task when a task finishes - #1663

Open
NathanGray-ChurchillNavigation wants to merge 2 commits into
aptly-dev:masterfrom
NathanGray-ChurchillNavigation:fix-task-queue-stall
Open

NathanGray-ChurchillNavigation wants to merge 2 commits into
aptly-dev:masterfrom
NathanGray-ChurchillNavigation:fix-task-queue-stall

Conversation

@NathanGray-ChurchillNavigation

@NathanGray-ChurchillNavigation NathanGray-ChurchillNavigation commented Nov 6, 2026 •

Copy link
Copy Markdown

Fixes #1662

Description of the Change

When a task finishes, the consumer now queues every IDLE task whose resources are free, instead of stopping at the first one. Each pick is still marked in use under the list lock before the scan moves on, so a later task that conflicts with an earlier pick stays blocked, and the channel sends still happen after unlocking (as #1529 set up).

A picked task stays IDLE until the consumer receives it, so tasks now carry an unexported queued flag, set under the lock wherever they are queued, and the rescan skips them. Without it, a task with no resources (which marks nothing in use) could be picked by two completions and run twice. Master has a narrower version of the same race, between RunTaskInBackground and a completion, which this also closes.

One completion can now start several tasks at once. Tasks with disjoint resources could already run in parallel when submitted directly, so this doesn't add a new kind of concurrency.

Tests:

  • TestAllUnblockedTasksStart fails on master: C stays IDLE while B runs. It also checks that a waiter that conflicts with B stays blocked.
  • TestReleasedTasksRunOnce releases 50 resource-free tasks at once and checks each runs exactly once. Without the queued flag it panics with a negative WaitGroup counter.

Both pass repeatedly with and without -race.

Checklist

  • allow Maintainers to edit PR (rebase, run coverage, help with tests, ...)
  • unit-test added (if change is algorithm)
  • functional test added/updated (if change is functional)
  • man page updated (if applicable)
  • bash completion updated (if applicable)
  • documentation updated
  • author name in AUTHORS

The consumer used to queue only the first IDLE task whose resources had
become free, so any other task unblocked by the same completion stayed
IDLE until some later task finished. Collect every runnable task under
the lock and queue them all after unlocking.

Fixes aptly-dev#1662
@codecov

codecov Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.64%. Comparing base (e35afce) to head (adf657f).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1663      +/-   ##
==========================================
- Coverage   77.91%   77.64%   -0.28%     
==========================================
  Files         165      165              
  Lines       16141    16141              
==========================================
- Hits        12577    12532      -45     
- Misses       2350     2400      +50     
+ Partials     1214     1209       -5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

A task picked by one completion stays IDLE until the consumer receives
it, so another completion could pick it again. Resources marked in use
prevent that for most tasks, but a task with no resources marks nothing,
and could run twice and drive the WaitGroups negative. Track that a task
was handed to the consumer and skip it when rescanning.
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.

Waiting tasks can stay IDLE after their resources are freed

1 participant