781flyingdutchman / background_downloader

Flutter plugin for file downloads and uploads
Other
157 stars 74 forks source link

ParallelDownloadTask: All Chunks Cancelled Unexpectedly #357

Open Rohan487 opened 1 month ago

Rohan487 commented 1 month ago

Describe the bug While testing ParallelDownloadTask ,all 10 parts download suddenly cancelled and got some errors in debug console

Logs If possible, include logs that capture the issue:

/WM-WorkerWrapper(32354): java.util.concurrent.CancellationException: Task was cancelled.
I/WM-WorkerWrapper(32354):  at androidx.work.impl.utils.futures.AbstractFuture.cancellationExceptionWithCause(AbstractFuture.java:1183)
I/WM-WorkerWrapper(32354):  at androidx.work.impl.utils.futures.AbstractFuture.getDoneValue(AbstractFuture.java:513)
I/WM-WorkerWrapper(32354):  at androidx.work.impl.utils.futures.AbstractFuture.get(AbstractFuture.java:474)
I/WM-WorkerWrapper(32354):  at androidx.work.impl.WorkerWrapper$2.run(WorkerWrapper.java:316)
I/WM-WorkerWrapper(32354):  at androidx.work.impl.utils.SerialExecutorImpl$Task.run(SerialExecutorImpl.java:96)
I/WM-WorkerWrapper(32354):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I/WM-WorkerWrapper(32354):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I/WM-WorkerWrapper(32354):  at java.lang.Thread.run(Thread.java:1012)
E/MethodChannel#com.bbflight.background_downloader(32354): Failed to handle method call
E/MethodChannel#com.bbflight.background_downloader(32354): kotlinx.serialization.SerializationException: Serializer for class 'Any' is not found.
E/MethodChannel#com.bbflight.background_downloader(32354): Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied.
E/MethodChannel#com.bbflight.background_downloader(32354): 
E/MethodChannel#com.bbflight.background_downloader(32354):  at kotlinx.serialization.internal.Platform_commonKt.serializerNotRegistered(Platform.common.kt:91)
E/MethodChannel#com.bbflight.background_downloader(32354):  at kotlinx.serialization.SerializersKt__SerializersKt.noCompiledSerializer(Serializers.kt:366)
E/MethodChannel#com.bbflight.background_downloader(32354):  at kotlinx.serialization.SerializersKt.noCompiledSerializer(Unknown Source:1)
E/MethodChannel#com.bbflight.background_downloader(32354):  at com.bbflight.background_downloader.BDPlugin.methodUpdateChunkStatus(BDPlugin.kt:1228)
E/MethodChannel#com.bbflight.background_downloader(32354):  at com.bbflight.background_downloader.BDPlugin.access$methodUpdateChunkStatus(BDPlugin.kt:56)
E/MethodChannel#com.bbflight.background_downloader(32354):  at com.bbflight.background_downloader.BDPlugin$onMethodCall$1.invokeSuspend(BDPlugin.kt:392)
E/MethodChannel#com.bbflight.background_downloader(32354):  at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
E/MethodChannel#com.bbflight.background_downloader(32354):  at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
E/MethodChannel#com.bbflight.background_downloader(32354):  at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:280)
E/MethodChannel#com.bbflight.background_downloader(32354):  at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
E/MethodChannel#com.bbflight.background_downloader(32354):  at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
E/MethodChannel#com.bbflight.background_downloader(32354):  at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source:1)
E/MethodChannel#com.bbflight.background_downloader(32354):  at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
E/MethodChannel#com.bbflight.background_downloader(32354):  at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source:1)
E/MethodChannel#com.bbflight.background_downloader(32354):  at com.bbflight.background_downloader.BDPlugin.onMethodCall(BDPlugin.kt:376)
E/MethodChannel#com.bbflight.background_downloader(32354):  at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:267)
E/MethodChannel#com.bbflight.background_downloader(32354):  at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:292)
E/MethodChannel#com.bbflight.background_downloader(32354):  at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:319)

E/MethodChannel#com.bbflight.background_downloader(32354):  at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
E/MethodChannel#com.bbflight.background_downloader(32354):  at android.os.Handler.handleCallback(Handler.java:942)
E/MethodChannel#com.bbflight.background_downloader(32354):  at android.os.Handler.dispatchMessage(Handler.java:99)
E/MethodChannel#com.bbflight.background_downloader(32354):  at android.os.Looper.loopOnce(Looper.java:240)
E/MethodChannel#com.bbflight.background_downloader(32354):  at android.os.Looper.loop(Looper.java:351)
E/MethodChannel#com.bbflight.background_downloader(32354):  at android.app.ActivityThread.main(ActivityThread.java:8381)
E/MethodChannel#com.bbflight.background_downloader(32354):  at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#com.bbflight.background_downloader(32354):  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
E/MethodChannel#com.bbflight.background_downloader(32354):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013)
I/om.app(32354): Background young concurrent copying GC freed 596235(18MB) AllocSpace objects, 1(28KB) LOS objects, 46% free, 20MB/38MB, paused 3.320ms,246us total 113.028ms

Same log was repeated 10 times cause chunks was 10

Code If possible, paste in the code snippet where you interact with the package:

final task = ParallelDownloadTask(
        url: downloadurl,
        filename: filename,
        directory: "files",
        allowPause: true,
        retries: 3,
        chunks: 10,
        headers: {'Connection': 'close'},
        updates: Updates.statusAndProgress,
        baseDirectory: BaseDirectory.applicationSupport);

    await FileDownloader().enqueue(task);

Additional context Add any other context about the problem here.

781flyingdutchman commented 1 month ago

Interesting! Does this happen immediately, early or later in the download process?

Rohan487 commented 1 month ago

Not immediately but after some time. I guess its becuase there is no retry machenism for chunks?

781flyingdutchman commented 1 month ago

It actually looks like a serialization problem, but likely one that only occurs in unusual circumstances (because that code hasn't changed for a while now). I need to look at it in more detail.

781flyingdutchman commented 1 month ago

Based on the logs it looks like you are using an older version of the plugin. Can you upgrade to the latest and check if the problem persists? Thanks

781flyingdutchman commented 1 month ago

Sorry, didn't mean to close it

Rohan487 commented 1 month ago

hey in latest version download parallel download is working fine , however I am seeing some unexpected behaviour with the progress callback of parallel download.

Screenshot

As you can see un screenshot it sometimes just pass the details of every chunk instead of a group as explained in doc.

781flyingdutchman commented 1 month ago

Which platform(s) does this happen on?

Rohan487 commented 4 weeks ago

I tested on android 13

781flyingdutchman commented 1 week ago

Strange - it suggests the child tasks are not marked as belonging to a parent task and I don't understand how that can be. Does this happen when the app has suspended (i.e. been in the background a long time)? It is possible that that somehow 'disconnects' the child tasks from the parent

Rohan487 commented 1 week ago

Yes, it's working fine when it's in foreground means when I am on download screen .

When I minimize it ( going to home ) and after sometime if I open it, it shows the all chunks.

781flyingdutchman commented 1 week ago

Ok that's helpful. Let me think about this.

781flyingdutchman commented 1 week ago

More questions as I try to debug this: 1) When this happens, does the progress bar of the "main" task (the one with the proper name you gave it) progress as usual, or does it stop? 2) Does the main task eventually complete, even as these child task notifications show up, or does it not complete? 3) For the child tasks (with the com.bbflight etc name): do these notifications appear a) when the app is in the background, or b) when you bring the app into the foreground? 4) For the child task, does the progress bar show progress as usual? Does it complete (and remove the notification)?

Thanks for your help.

Rohan487 commented 1 week ago
  1. I didn't focus on it, but maybe it was progressing. However, the child tasks were not progressing, and the progress bar was stuck for all of them.
  2. The main task completes successfully.Notifications for the child tasks do not appear in either case (foreground or background).
  3. The progress bar for the child tasks does not show any progress; it's stuck.

I use the task tracking database File Filedownloader().database.allRecords() to display the list of tasks.

781flyingdutchman commented 1 week ago

Hang on - I thought the screenshot you shared showed Android notifications showing up for the child tasks. Is that screenshot your own progress widget (using Filedownloader().database.allRecords())? If so, you should exclude tasks that have their group field set to FileDownloader.chunkGroup as that is a reserved group name used by the child tasks of the parallel download. You should never show those. If you normally don't assign a group, then you can get just the default tasks using Filedownloader().database.allRecords(group: FileDownloader.defaultGroup).

Can you confirm this is the issue, and nothing to do with notifications?