feat(windows): workmanager_windows — Task Scheduler based background execution (fixes #324) - #717
Draft
ened wants to merge 1 commit into
Draft
feat(windows): workmanager_windows — Task Scheduler based background execution (fixes #324)#717ened wants to merge 1 commit into
ened wants to merge 1 commit into
Conversation
…d execution Implements WorkmanagerPlatform for Windows via the schtasks CLI (no COM, no native code): one-off (/SC ONCE) and periodic (/SC DAILY /RI) task registration, on-disk JSON payloads, cancellation, status queries, and a headless --background-task runner mirroring workmanager_web's execution registry. Includes core integration (platform selection branch), docs and pure-Dart unit tests with an injectable process runner.
|
To preview the documentation for this pull request, visit the following URL: docs.page/fluttercommunity/flutter_workmanager~717
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the Windows desktop port for
flutter_workmanager(tracked in #324):a new federated package
workmanager_windowsimplementingWorkmanagerPlatformon top of Task Scheduler, plus minimal coreintegration and docs.
v1 uses the
schtasksCLI only — no COM, no C++, nowin32dependency,pure Dart (the design doc's "schtasks CLI" option, which keeps the package
fully unit-testable off Windows).
Fixes #324
What's implemented
schtasks /Create /SC ONCEatnow + initialDelay(minute granularity; a zero/sub-minute delay is rounded up to the next
minute so the task always fires).
schtasks /Create /SC DAILY /RI <minutes>; frequencyclamped to 1 minute..416 days (the
schtasks /RIrange).inputDatapersistence — Android-style on-disk payload: a JSON fileper
uniqueNameunder%LOCALAPPDATA%\workmanager_windows\payloads,handed to the headless process via
--payload-file <path>.cancelByUniqueName/cancelAll—schtasks /End(runninginstance) +
schtasks /Delete+ payload cleanup; idempotent for missingtasks.
isScheduledByUniqueName/printScheduledTasks— viaschtasks /Query(CSV parsed and filtered to tasks owned by the plugin,prefixed
workmanager_).Headless execution pattern
Mirrors
workmanager_web/lib/execution.dart: a small Flutter-free registry(
WorkmanagerExecution) holds the handler registered by the callbackdispatcher, and a runner detects the Task Scheduler launch argument in
main():The runner parses
--background-task <taskName>, loads the payload JSON,invokes the registered handler, logs the result and exits with
0/1(theexit code becomes Task Scheduler's "Last Task Result"). The dispatcher
registers its handler through
WorkmanagerWindows().executeTask(...)(theregistry), not
Workmanager().executeTask(...)— the handler runs in aseparate process on Windows.
Unsupported surface (kept honest)
networkType,requiresCharging,requiresDeviceIdle,...) and backoff are accepted but ignored (documented no-ops) —
schtasksdoes not exposeWakeToRun/idle/battery/AC/network conditions.existingWorkPolicyis not honored — re-registering auniqueNamealways replaces the task (
/F, which matches WorkManager's defaultREPLACE policy).
tagaccepted but ignored;cancelByTagthrowsUnsupportedError.registerProcessingTask,registerHealthResearchTask,registerContinuedProcessingTask) throwUnsupportedError(same as web).requires credentials/SYSTEM and therefore admin — documented as an
opt-in an admin can enable manually; not exposed in the v1 API.
schtasksparses dates with the system regionalformat; v1 emits
MM/DD/YYYY(en-US assumed).Test approach
ProcessRunneris injectable (default impl isdart:io Process.run), so alltests run without Windows:
test/schtasks_test.dart— command construction:/SC ONCEvs/SC DAILY|/RI,/TRquoting with spaces,/Delete,/Query,frequency clamping, date/time formatting, CSV parsing.
test/payload_store_test.dart— JSON payload round-trip, null inputData,filename sanitization (path traversal), delete/deleteAll, non-JSON
rejection.
test/execution_test.dart—--background-task/--payload-fileargparsing and
runBackgroundTaskexit codes (0 success / 1 failure, handlerthrows, no handler).
test/workmanager_windows_test.dart— full platform surface against afake process runner (registration args, rollback on
schtasksfailure,cancel/cancelAll, queries, dispatcher wiring, unsupported surface).
Gates run:
melos bootstrap✓,dart analyze(no issues) ✓,dart test(41 pure-Dart tests) +
flutter test(61 total) all pass ✓,dart format --set-exit-if-changedclean ✓. Noflutter build windowsrun— the package is pure Dart and needs no Windows toolchain.
Notes for reviewers
workmanagerdepends onworkmanager_windowsvia a path dependency(the package is not published yet), so
dart analyzeonworkmanagerreports the expected
invalid_dependencywarning and the CIpublishablejob will fail on this draft. Onceworkmanager_windowsispublished, the dependency flips to a caret constraint (melos release
handles this).
BackgroundTaskResultmigration (feat!: BackgroundTaskResult enum instead of bool (fixes #23) #712): this PR deliberately buildsagainst the current
Future<bool>handler contract; the desktop packageswill migrate to the
BackgroundTaskResultenum together with feat!: BackgroundTaskResult enum instead of bool (fixes #23) #712.workmanager_linuxand touchesthe same platform-selection block in
workmanager_impl.dart— expect amerge conflict there; trivial to resolve in either direction.
yet; a
windows-latestjob forworkmanager_windows(analyze + test) is anatural follow-up, as is wiring the example app.
run → cancel) is recommended before this leaves draft.