Found while auditing for bugs similar to #66/#67 (DartWorker cancellation not reaching the running work).
The bug
HttpDownloadWorker.downloadWithBackgroundSession and HttpUploadWorker.uploadWithBackgroundSession (both gated by useBackgroundSession: true, iOS-only, "survives app termination") each register their URLSessionDownloadTask/URLSessionUploadTask with BackgroundSessionManager under a throwaway random id:
let taskId = "download-\(UUID().uuidString)" // HttpDownloadWorker
let taskId = "upload-\(UUID().uuidString)" // HttpUploadWorker
NativeWorkManager.cancel(taskId) / cancelAll() / cancelByTag() all call BackgroundSessionManager.shared.cancel(taskId: <the real plugin taskId>), which looks up the task by that id. Since the background-session download/upload was registered under a different, randomly-generated id that's never exposed anywhere, this lookup always misses — cancelling one of these tasks is a complete no-op for the actual network transfer. It keeps uploading/downloading in the background regardless of cancel().
Contrast with HttpDownloadWorker's foreground download path, which correctly implements stop() (currentDownloadTask?.cancel()) — background-session transfers have no equivalent because stop() was never wired to them, and the id mismatch means even calling BackgroundSessionManager.cancel() directly wouldn't help without the fix.
Fix
Both functions now accept the real task id (extracted from __taskId in the input JSON, the same way HttpDownloadWorker.doWork already does for progress reporting) and register with BackgroundSessionManager under that id instead of a random one — falling back to a random id only if none is available. No change needed to BackgroundSessionManager itself; the existing cancel(taskId:) calls already wired into every cancel path now simply find the right task.
Fixed on fix/issue-66-dart-worker-cancellation (same branch as #67, PR #68) — regression test to follow in the same PR.
Found while auditing for bugs similar to #66/#67 (DartWorker cancellation not reaching the running work).
The bug
HttpDownloadWorker.downloadWithBackgroundSessionandHttpUploadWorker.uploadWithBackgroundSession(both gated byuseBackgroundSession: true, iOS-only, "survives app termination") each register theirURLSessionDownloadTask/URLSessionUploadTaskwithBackgroundSessionManagerunder a throwaway random id:NativeWorkManager.cancel(taskId)/cancelAll()/cancelByTag()all callBackgroundSessionManager.shared.cancel(taskId: <the real plugin taskId>), which looks up the task by that id. Since the background-session download/upload was registered under a different, randomly-generated id that's never exposed anywhere, this lookup always misses — cancelling one of these tasks is a complete no-op for the actual network transfer. It keeps uploading/downloading in the background regardless ofcancel().Contrast with
HttpDownloadWorker's foreground download path, which correctly implementsstop()(currentDownloadTask?.cancel()) — background-session transfers have no equivalent becausestop()was never wired to them, and the id mismatch means even callingBackgroundSessionManager.cancel()directly wouldn't help without the fix.Fix
Both functions now accept the real task id (extracted from
__taskIdin the input JSON, the same wayHttpDownloadWorker.doWorkalready does for progress reporting) and register withBackgroundSessionManagerunder that id instead of a random one — falling back to a random id only if none is available. No change needed toBackgroundSessionManageritself; the existingcancel(taskId:)calls already wired into every cancel path now simply find the right task.Fixed on
fix/issue-66-dart-worker-cancellation(same branch as #67, PR #68) — regression test to follow in the same PR.