You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On version 8.9.3, Huawei P40 Pro, EMUI 12 (Android 10):
I am working on implementing really long background uploads.
I am now struggling a bit to keep the tasks running and to be able to restart them when keeping the app in a suspended state.
I use the enquing method for the scheduling of tasks:
@pragma('vm:entry-point')
Future<String> testWebAPIUpload(Map<String, dynamic> json) async {
try {
UploadParams params =UploadParams.fromJson(json);
File persistentFile =File(params.localFilePath);
if (!persistentFile.existsSync()) {
debugPrint('File does not exist after moving: ${persistentFile.path}');
returnUploadFileResult.fileNotFound.toJson();
}
final (baseDirectory, directory, filename) =awaitTask.split(filePath: persistentFile.path);
awaitFileDownloader().enqueue(
UploadTask(
filename: filename,
directory: directory,
baseDirectory: baseDirectory,
url:'${params.webApiBaseUrl}/projects/${params.projectId}/rushfile',
urlQueryParameters: { 'jwt': params.token, 'filepath': params.distantFilePath },
post:'binary',
httpRequestMethod:'POST',
mimeType:'application/octet-stream',
updates:Updates.statusAndProgress,
metaData:jsonEncode({'localFilePath': persistentFile.path, 'distantFilePath': params.distantFilePath, 'projectId': params.projectId, 'webApiBaseUrl': params.webApiBaseUrl, 'token': params.token}),
// options: TaskOptions(onTaskStart: onUploadTaskStart)
options:TaskOptions(onTaskStart: onUploadTaskStart)
)
);
returnUploadFileResult.uploadEnqueued.toJson();
} catch (e) {
debugPrint('Enqueueing of upload of file failed for an unkown reason: $e');
returnUploadFileResult.unknownError.toJson();
}
}
I/BackgroundDownloader(31515): Enqueuing task with id 1140406881
D/HwCustConnectivityManagerImpl(31515): isBlockNetworkRequestByNonAis, INVALID_SUBSCRIPTION_ID
I/ConnectivityManager(31515): requestNetwork and the calling app is: com.bbflight.background_downloader_example
I/TaskWorker(31515): onTaskStart callback for taskId 1140406881
I/TaskWorker(31515): Starting task with taskId 1140406881
I/NotificationManager(31515): com.bbflight.background_downloader_example: cancel(0)
I/flutter (31515): Task with id 1140406881 is now running
D/TaskWorker(31515): Binary upload for taskId 1140406881
I use the runInForeground option, to allow me to go longer than the 9 minutes mark, but it doesn't have an impact yet, since the stops occurs after 6 minutes:
I am currently trying this approach for failed tasks (which all eventualy do while suspended after few minutes in suspended state):
// Listen to updates and processFileDownloader().updates.listen((update) async {
switch (update) {
caseTaskStatusUpdate():switch (update.status) {
caseTaskStatus.paused:
loadUploadResult ='Paused ...';
break;
caseTaskStatus.canceled:debugPrint('Task with id ${update.task.taskId} has been cancelled');
break;
caseTaskStatus.enqueued:debugPrint('Task with id ${update.task.taskId} is enqueued');
break;
caseTaskStatus.complete:debugPrint('Task with id ${update.task.taskId} is complete');
try {
var path =jsonDecode(update.task.metaData)['localFilePath'];
debugPrint('Deleting file from persitent storage: $path');
var file =File(path);
if(!file.existsSync()) {
debugPrint("Could not delete file, file not found");
break;
}
file.deleteSync();
debugPrint("File deleted from persitent storage");
break;
} catch (e) {
debugPrint('Could not delete file from persitent storage: $e');
break;
}
caseTaskStatus.failed:debugPrint('Task with id ${update.task.taskId} has failed.');
debugPrint('Task with id ${update.task.taskId} failure exeption: ${update.exception}');
debugPrint('Task with id ${update.task.taskId} failure responseBody: ${update.responseBody}');
debugPrint('Trying to re-enqueue task with id ${update.task.taskId}');
try {
bool enqueued =awaitFileDownloader().enqueue(update.task);
debugPrint('Task with id ${update.task.taskId} re-enqueued successfuly : $enqueued');
} catch (e) {
debugPrint('Could not re-enqueue task with id ${update.task.taskId}');
break;
}
break;
caseTaskStatus.running:debugPrint('Task with id ${update.task.taskId} is now running');
break;
default:
}
With this setup, the typical big file upload goes as follow with task running in the background (app reduced and phone locked):
File uploaded steadily for around (~6 minutes).
Uploading stops silently (no more bytes sent to server, no errors, no new logs).
Then I could wait indefinetly, but nothing else happens.
Then finally when reopening the app to the foreground, I get an java.net.ProtocolException: unexpected end of stream:
W/TaskWorker(25065): Error for taskId 1140406881: unexpected end of stream
W/TaskWorker(25065): java.net.ProtocolException: unexpected end of stream
W/TaskWorker(25065): at com.android.okhttp.internal.http.Http1xStream$FixedLengthSink.close(Http1xStream.java:302)
W/TaskWorker(25065): at com.android.okhttp.okio.RealBufferedSink.close(RealBufferedSink.java:242)
W/TaskWorker(25065): at com.android.okhttp.okio.RealBufferedSink$1.close(RealBufferedSink.java:210)
2
W/TaskWorker(25065): at java.io.FilterOutputStream.close(FilterOutputStream.java:159)
W/TaskWorker(25065): at kotlin.io.CloseableKt.closeFinally(Closeable.kt:56)
W/TaskWorker(25065): at com.bbflight.background_downloader.UploadTaskWorker$processBinaryUpload$3.invokeSuspend(UploadTaskWorker.kt:216)
W/TaskWorker(25065): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
W/TaskWorker(25065): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
W/TaskWorker(25065): at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
W/TaskWorker(25065): at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:100)
W/TaskWorker(25065): at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
W/TaskWorker(25065): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
W/TaskWorker(25065): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
W/TaskWorker(25065): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
I/flutter (25065): Task with id 1140406881 has failed.
I/flutter (25065): Task with id 1140406881 failure exeption: TaskException: Error for url https://redacted&filepath=VID_20250115_110801.mp4&range=bytes%3D1747361792-4224690610&x-total-size=4224690611 and /data/user/0/com.bbflight.background_downloader_example/files/VID_20250115_110801.mp4: unexpe
I/flutter (25065): Task with id 1140406881 failure responseBody: null
Then my re-enquing mechanism kicks-in:
I/flutter (25065): Trying to re-enqueue task with id 1140406881
With a simple (as stated above):
bool result =awaitFileDownloader().enqueue(task);
But what would be the best scenario, would be to allow the renquing process and failure detection to take place all while the app is suspended.
For reference , when staying with the app opened the whole time, the uploading also stops after 6 minutes:
Task stop uploading silently after 6 minutes.
After ~3 minutes the task fail is detected with the following error:
I/TaskWorker(31515): Could not read response body from httpResponseCode 502: java.io.FileNotFoundException: https://redacted&filepath=VID_20250115_110801.mp4&range=bytes%3D3097788416-4224690610&x-total-size=4224690611
I/TaskWorker(31515): Response code 502 for upload of /data/user/0/com.bbflight.background_downloader_example/files/VID_20250115_110801.mp4 to https://redacted&filepath=VID_20250115_110801.mp4&range=bytes%3D3097788416-4224690610&x-total-size=4224690611
I/flutter (31515): Task with id 2316321278 has failed.
I/flutter (31515): Task with id 2316321278 failure exeption: TaskHttpException, response code 502: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
I/flutter (31515): <html><head>
I/flutter (31515): <title>502 Bad Gateway</title>
I/flutter (31515): </head><body>
I/flutter (31515): <h1>Bad Gateway</h1>
I/flutter (31515): <p>The proxy server received an invalid
I/flutter (31515): response from an upstream server.<br />
I/flutter (31515): </p>
I/flutter (31515): </body></html>
I/flutter (31515):
I/WM-WorkerWrapper(31515): Work [ id=958e0f38-0f22-4e15-983e-64563af733a9, tags={ com.bbflight.background_downloader.UploadTaskWorker, BackgroundDownloader, taskId=2316321278, group=default } ] was cancelled
I/WM-WorkerWrapper(31515): java.util.concurrent.CancellationException: Task was cancelled.
I/WM-WorkerWrapper(31515): at androidx.work.impl.utils.futures.AbstractFuture.cancellationExceptionWithCause(AbstractFuture.java:1183)
I/WM-WorkerWrapper(31515): at androidx.work.impl.utils.futures.AbstractFuture.getDoneValue(AbstractFuture.java:513)
I/WM-WorkerWrapper(31515): at androidx.work.impl.utils.futures.AbstractFuture.get(AbstractFuture.java:474)
I/WM-WorkerWrapper(31515): at androidx.work.impl.WorkerWrapper$2.run(WorkerWrapper.java:316)
I/WM-WorkerWrapper(31515): at androidx.work.impl.utils.SerialExecutorImpl$Task.run(SerialExecutorImpl.java:96)
I/WM-WorkerWrapper(31515): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
I/WM-WorkerWrapper(31515): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
I/WM-WorkerWrapper(31515): at java.lang.Thread.run(Thread.java:929)
I/flutter (31515): Task with id 2316321278 failure responseBody: null
I/flutter (31515): Trying to re-enqueue task with id 2316321278
D/BackgroundDownloader(31515): Registering callbackDispatcher handle 6720582723587629712
Then the task is re-enqueued without issues:
I/NotificationManager(31515): com.bbflight.background_downloader_example: cancel(0)
I/flutter (31515): BaseDownloader>WARNING: 2025-01-24 15:26:47.747305: Could not register callbackDispatcher
I/BackgroundDownloader(31515): Enqueuing task with id 2316321278
D/HwCustConnectivityManagerImpl(31515): isBlockNetworkRequestByNonAis, INVALID_SUBSCRIPTION_ID
I/ConnectivityManager(31515): requestNetwork and the calling app is: com.bbflight.background_downloader_example
I/flutter (31515): Task with id 2316321278 re-enqueued successfuly : true
I/flutter (31515): Task with id 2316321278 is enqueued
I/TaskWorker(31515): onTaskStart callback for taskId 2316321278
I/TaskWorker(31515): Starting task with taskId 2316321278
I/flutter (31515): Task with id 2316321278 is now running
I/TaskWorker(31515): TaskId 2316321278 will run in foreground
D/TaskWorker(31515): Binary upload for taskId 2316321278
A thing to be noted in the log is that the renqueued task is marked as it will run in the foreground but not at initial enqueue. Maybe a configuration bad timing on my end ?
Edit:
I changed my use of flutterCompute for the initial enqueueing process, for a regural function call and now the task is started in foreground.
Thanks a lot for your work.
The text was updated successfully, but these errors were encountered:
and that is outside of the control of Flutter or the plugin. What happens when the task is killed is complete silence - there is no way to react to that (i.e. no callback are called, no status updates given, etc). In the latest version of the package, if you track tasks in the database and use start or rescheduleKilledTasks (one or the other, not both) then all killed tasks will automatically be rescheduled.
You should not use the plugin from anything other than the main isolate, so you cannot call it using compute.
Hello,
On version 8.9.3, Huawei P40 Pro, EMUI 12 (Android 10):
I am working on implementing really long background uploads.
I am now struggling a bit to keep the tasks running and to be able to restart them when keeping the app in a suspended state.
I use the enquing method for the scheduling of tasks:
I use the
runInForeground
option, to allow me to go longer than the 9 minutes mark, but it doesn't have an impact yet, since the stops occurs after 6 minutes:I am currently trying this approach for failed tasks (which all eventualy do while suspended after few minutes in suspended state):
With this setup, the typical big file upload goes as follow with task running in the background (app reduced and phone locked):
java.net.ProtocolException: unexpected end of stream
:With a simple (as stated above):
But what would be the best scenario, would be to allow the renquing process and failure detection to take place all while the app is suspended.
For reference , when staying with the app opened the whole time, the uploading also stops after 6 minutes:
A thing to be noted in the log is that the renqueued task is marked as it will run in the foreground but not at initial enqueue. Maybe a configuration bad timing on my end ?
Edit:
I changed my use of
flutterCompute
for the initial enqueueing process, for a regural function call and now the task is started in foreground.Thanks a lot for your work.
The text was updated successfully, but these errors were encountered: