react-native-queue
react-native-queue copied to clipboard
the current executing job is lost when force terminate app(in android)
if I set a very short timeout for my job for test, the job will always fail and retry, but if I terminate the app and restart, that job has gone! the next job is executing. is this a bug??
If I had to guess the job is stuck in "active" state so it is not being picked up by the queue the next time the queue tries to grab a job off the stack.
See this section of code for the realm query that grabs the next job(s) to process off the queue stack.
https://github.com/billmalarky/react-native-queue/blob/master/Models/Queue.js#L273-L275
The solution, which would have to be developed, would be some sort of process that looks for "stuck" jobs and marks them not active anymore. The question at that point is what interval to check for stuck jobs, because technically you can have a job with no timeout set (indefinite timeout) that could run forever, and we wouldn't want to randomly set that job to no longer active if it truly was still running.
The popular node.js library "kue" has dealt with this problem before so perhaps we can get inspiration there.
https://github.com/Automattic/kue#unstable-redis-connections
why not marking all job as inactive
on startup??
just because the unexpected termination, their state were not reset as normal.
@billmalarky I have add the reset function as my suggestion and it works correctly with force termination. but there's another problem: the failed jobs will live in realm forever, what about if their amount grows very fast??
The reset function may work for your specific use case, but it is more complex than that for a general use case because you have to consider that multiple RNQ modules can be initialized at once. For example you could be using RNQ in a periodic background task that runs the same time you are also using it in a focused app in the foreground.
As you can see with the above described scenario when the background task fires up and inits RNQ all the jobs marked as active would be reset to inactive even though they could very well be actively being processed by RNQ running I'm the foreground app.
So it's a bit tricky to solve in a general way.
As for failed jobs hanging around, that is a TODO to handle garbage collection. It has been considered lower priority simply because failed job data piling up hasn't become a serious issue for anyone yet. Though when I am able to add that functionality it will be done via "compactOnLaunch" in this file if I had to guess.
https://github.com/billmalarky/react-native-queue/blob/master/config/Database.js
On Wed, Jun 13, 2018, 11:18 PM wellbye [email protected] wrote:
@billmalarky https://github.com/billmalarky I have add the reset function as my suggestion and it works correctly with force termination. but there's another problem: the failed jobs will live in realm forever, what about if their amount grows very fast??
— You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/billmalarky/react-native-queue/issues/24#issuecomment-397157611, or mute the thread https://github.com/notifications/unsubscribe-auth/ABxTU6dtynE6DLtozWQEaV5swRqPEl4Rks5t8dYcgaJpZM4Umwju .
thanks very much, I have understood the problem. wish for improvings~
@fatfatson how did you make your reset function?
This is roughly what I did to "reset" things @carllippert but I removed a lot of things that were extraneous to this library so it's probably not exactly how you should implement it.
import queueFactory from 'react-native-queue'
import Database from 'react-native-queue/config/Database'
restartQueue = () => {
return queueFactory().then(queue => {
// whatever action you do to start up your queue
})
}
export function resetActiveJobs() {
// Reset the jobs that react-native-queue immediately marked as "active" in realm.
// Else, if the user killed the app before the job finished, when the app restarts
// the job is still "active" so it doesn't requeue.
Database.getRealmInstance().then(realm => {
realm.write(() => {
let jobs = realm.objects('Job').filtered('active == TRUE AND failed == null');
if (jobs.length > 0) {
for (let job of jobs) {
job.active = false
}
}
})
}).then(() => restartQueue())
}
... and I run resetActiveJobs()
when I start up the app.
Any improvements?
In my case, this functionality is very important because I want all jobs to get complete even if the user closes app/restarts phone/etc.
For now, @famousfilm implementation has worked. Thank you.