Skip to content

fix(android): admit foreground workers before promoting to foreground (#95) - #96

Merged
vietnguyentuan2019 merged 1 commit into
mainfrom
fix/issue-95-foreground-admission
Nov 9, 2026
Merged

vietnguyentuan2019 merged 1 commit into
mainfrom
fix/issue-95-foreground-admission

Conversation

@vietnguyentuan2019

Copy link
Copy Markdown
Contributor

Refs #95 (doesn't close it, see below).

With maxConcurrentTasks: 1, ForegroundNativeWorker called setForeground() before the TaskConcurrency permit, so every waiting worker still promoted itself and booted its own Flutter engine. Callbacks were serialized, promotion wasn't. That ordering came in with the limiter in 1.9.0 (#84).

Order is now: wait for permit -> promote -> run -> release. Promotion and execution share one permit (no nested acquire), waiters don't promote, cancel frees the slot. Background fallback when promotion is rejected is unchanged, CancellationException is rethrown, and the cancel path logs phase / work id / isStopped / stopReason / runAttemptCount. Periodic scheduling is untouched.

Tests

  • ForegroundAdmissionTest (JVM, 6 tests): 6/6 pass
  • 2 issue_95 device tests: smoke only, they also pass on 1.9.0 code since the limiter already serialized callbacks
  • Pixel 6 Pro (Android 17), limit=1, periodic FGS Dart workers: 5 promotions within 87 ms before, one per ~2 s after. 12 workers on the old code were all promoted within ~500 ms
  • all issue_* device tests pass at limit 1 and 2
  • iOS has no foreground promotion and already acquires the limiter before execution, so not affected (not run on iOS)

Not confirmed
Couldn't reproduce the reported cancellation, not even on 1.9.0 with 12 workers. Cause is still unknown, so I'd keep #95 open until we get a stop reason from the reporter. Didn't verify multiple periodic cycles either.

…#95)

ForegroundNativeWorker called setForeground() before TaskConcurrency, so with
maxConcurrentTasks: 1 every waiting worker still promoted itself and booted its
Flutter engine. Order is now: wait for permit -> promote -> run -> release,
sharing one permit. Background fallback on rejected promotion is kept,
CancellationException is rethrown, and the cancel path logs phase, work id,
isStopped, stopReason and runAttemptCount.

Tests: ForegroundAdmissionTest (6, JVM), two issue_95 device smoke tests, FGS
demo button. On an API 34 emulator promotions went from 6 within ~130 ms to one
per ~0.6 s. The reported cancellation itself is not reproduced.
@vietnguyentuan2019
vietnguyentuan2019 merged commit b4822d8 into main Nov 9, 2026
13 checks passed
@vietnguyentuan2019
vietnguyentuan2019 deleted the fix/issue-95-foreground-admission branch November 10, 2026 23:36
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