Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot stop resumed tasks by checkForExistingDownloads #26

Open
scremona-navico opened this issue Sep 4, 2024 · 2 comments
Open

Cannot stop resumed tasks by checkForExistingDownloads #26

scremona-navico opened this issue Sep 4, 2024 · 2 comments

Comments

@scremona-navico
Copy link

scremona-navico commented Sep 4, 2024

Bug Report
iOS Simulator 15.5 (19F70)
Actual Device iPhone 7 15.8.3

Environment

React: 17.0.2
React native: 0.67.5
react-native-background-downloader: 3.2.1

Target Platform:
iOS (15.8.3/15.5)

Expected Behavior

I expect to be able to pause/resume/stop a task coming from checkForExistingDownloads.

Actual Behavior

Once my task is paused and then resumed, I cannot stop it anymore. It's a sort of zombie.
This happens just if I retrieve the tasks with checkForExistingDownloads.

If I store the object in a property of the class, ( this.task = download({... ) and then I execute the pause/resume/stop actions on it, everything works fine.

But if the task is coming from checkForExistingDownloads, as I pause it and then resume it, I cannot stop it.

Trying to stop it multiple times, on the other hand, generates multiple tasks that are as well downloaded in the background.

Steps to Reproduce

  1. Start the download providing an id.
  2. Pause the download, retrieving the task by filtering the checkForExistingDownloads result by the provided id.
  3. Resume the download, again retrieving it from checkForExistingDownloads.
  4. Stop it, filtering again the checkForExistingDownloads output by the known id.

You'll see the logs and the percentage going on.

Stopping several times the task coming from checkForExistingDownloads doesn't have any effect at all.
Even worst.
I can see from the logs the number of pending tasks increasing (picture in attachment).

From the snack that follows execute these steps:

  1. startDownload()
  2. pauseDownload()
  3. resumeDownload()
  4. stopDownload()
  5. eventually to stop all the tasks without any filter by id: stopAllDownloads() that logs the active tasks.

`
const jobId = 'file123';
// Class and state declaration
task = undefined;

startDownload = () => {
this.task = download({
id: jobId,
url: 'https://212.183.159.230/200MB.zip',
destination: ${directories.documents}/200MB.zip,
metadata: {},
})
.begin(({expectedBytes}: {expectedBytes: number}) => {
this.expectedBytes = expectedBytes;
devLog(Going to download ${expectedBytes} bytes!);
devLog('Task: ', this.task);
})
.progress(data => {
devLog('Downloaded: ', data);
this.setState({percentage: Number(data) * 100});
})
.done(data => {
devLog('Download is done!', data);
this.task = undefined;
completeHandler(jobId);
})
.error(error => {
this.task = undefined;
devLog('Download canceled due to error: ', error);
});
};

stopDownload = () => {
devLog('stopDownload');
checkForExistingDownloads().then(tasks => {
const task = tasks.find(t => t.id === jobId);
devLog('Stop the task: ', task);
task?.stop();
});
this.setState({percentage: 0});
};

pauseDownload = () => {
devLog('pauseDownload');
checkForExistingDownloads().then(tasks => {
const task = tasks.find(t => t.id === jobId);
devLog('Pause the task: ', task);
task?.pause();
});
};

resumeDownload = () => {
devLog('resumeDownload');
checkForExistingDownloads().then(tasks => {
const task = tasks.find(t => t.id === jobId);
devLog('Resume the task: ', task);
task?.resume();
});
};

stopAllDownloads = async () => {
const tasks = await checkForExistingDownloads();
devLog(
'Stopping all the existing tasks from checkForExistingDownloads:',
tasks.length,
);
for (const task of tasks) {
task.stop();
}
};

// These tasks acting directly to the class property work like a charm:
pauseDownloadByTask = () => {
devLog('Pausing the task: ', this.task);
this.task?.pause();
};

stopDownloadByTask = () => {
devLog('Stopping the task: ', this.task);
this.task?.stop();
};

resumeDownloadByTask = () => {
devLog('Resuming the task: ', this.task);
this.task?.resume();
};
`

01_PAUSE_WORKS.mov
02_RESUME_THEN_STOP_NOT_WORKING.mov
03_STOPPING_AGAIN_NOT_WORKING.mov
severalTasksAreCreated
@YohayBar
Copy link

Having the same issue:
Decided to not use pause /resume on iOS and when required just stop the task entirely both on Android and iOS.
Also try to only call checkForExistingDownloads from one place in the codebase and call task stop if needed just after.
Based on the documentation checkForExistingDownloads also resume download on iOS so a secondary call may trigger unintended resume

@YohayBar
Copy link

As a suggestion for the library maintainers - consider not to resume download when calling checkForExistingDownloads.

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

No branches or pull requests

2 participants