Closed lognaturel closed 5 years ago
@grzesiek2010 you are too fast! We've talked to @jd-alexander about this issue, so I'll be reassigning it to him.
@grzesiek2010 you are too fast! We've talked to @jd-alexander about this issue, so I'll be reassigning it to him.
No problem. I have other issues, just wanted to do that after them or in the middle if I'm free. Btw not that fast, I claimed the issue one hour after you had created it :smile:
Background
So I have been doing some research on this matter and based on my findings the recommended approach to running any form of background jobs is to utilize the job scheduling capabilities that are provided in Android JetPack's Work Manager. The JobScheduler
was being touted as the new defacto standard for backgrounding jobs but it's only compatible with apps targeting API 21 and above while the Firebase dispatcher was created as a compat variant for lower APIs. The introduction of the WorkManager
created a unified approach to this where it acts as an abstraction layer above the JobScheduler, Firebase Dispatcher and AlarmManager choosing the appropriate execution operation based on API level, constraints, and availability of system dependencies ( such as Google Play Services).
Current Architecture
Currently, the auto send functionality works with the NetworkReceiver
where it's triggered when a form is marked as finalized and when a connectivity event occurs eg. wifi connectivity. It doesn't care for individual form uploads as it operates on the entire group of finalized forms that haven't been submitted.
Migration options with the Work Manager
Based on what I have seen with the WorkManager there's no way to mimic the NetworkReceiver
s behavior because it's API doesn't allow jobs to be triggered periodically with network changes. The only way this could be done is if a single job is being triggered when a network event occurs and it gets marked as failed even if it succeeds so it never leaves the queue.
So the approaches we can take are
Maintain the current architecture that we have where every time there’s a connectivity change we check for a finalized form and then try to upload that. Pros - Would utilize most of the code we currently have. Cons - We would have to do something that’s against the WorkManager’s workflow which is to make the worker retry even if the task was successful so when a connectivity change happens again it’s run.
We can break each finalized form operation into a single job so when a form is finalized that job is added to the queue, execution occurs immediately if internet is present and if not then it waits on the connectivity event. This would involve us passing one instance id to the respective uploaders each time instead of an array of all forms present since each job would have the single responsibility of an instance.
Let me know if you have any thoughts on this. I am trying to think of the best approach to take with the direction the Android APIs are going in with respect for the different API levels and constraints being posed for background operations.
Thanks, @jd-alexander. Would also be great to get your thoughts, @grzesiek2010, since it seems you may have had some ideas as well.
It looks like WorkManager
is nearly identical in goals to the android-job
dependency we already have and that android-job
will soon be deprecated. So perhaps one first thing to do is migrate current uses of android-job
to WorkManager
- https://github.com/evernote/android-job/issues/520.
What about enqueuing a job that sends all forms with unsent status and, if the job succeeds and auto-send is still on, enqueues the same job again?
It looks like WorkManager is nearly identical in goals to the android-job dependency we already have and that android-job will soon be deprecated. So perhaps one first thing to do is migrate current uses of android-job to WorkManager - evernote/android-job#520.
Yes, I could work on doing this migration.
What about enqueuing a job that sends all forms with unsent status and, if the job succeeds and auto-send is still on, enqueues the same job again?
Yes, that would work well. Good idea.
There are some questions at https://github.com/opendatakit/collect/pull/2508#issuecomment-416070180 about whether a Play Services update will be needed and how likely that would be to impact users.
This line from https://developer.android.com/topic/libraries/architecture/workmanager/ makes me think we're probably ok:
WorkManager chooses an appropriate way to schedule a background task--depending on the device API level and included dependencies
I think the way to check will be to update all the dependencies as needed, make some WorkManager
calls, compile, and see if google_play_services_version
changes. It's currently set to 10084000
.
I think the way to check will be to update all the dependencies as needed, make some WorkManager calls, compile, and see if google_play_services_version changes. It's currently set to 10084000.
Okay!
Next steps for moving this forward will be to :
WorkManager
refactor. AutoSendWorker
that will be responsible for doing auto-sends when forms are finalized. In terms of the migrating the auto-send functionality, the worker will be enqueued every time a finalized form is saved if another job isn't current on the queue. This is necessary because each AutoSendWorker
performs sends on all finalized forms that are marked with auto-send so once the current job hasn't been executed it will automatically send the most recent finalized forms. the AutoSendWorker
has a network constraint attached to it so that could cause it to remain in the queue until a network event occurs.
Hello @jd-alexander, you claimed this issue to work on it, but this issue and any referenced pull requests haven't been updated for 10 days. Are you still working on this issue?
If so, please update this issue by leaving a comment on this issue to let me know that you're still working on it. Otherwise, I'll automatically remove you from this issue in 5 days.
If you've decided to work on something else, simply comment @opendatakit-bot unclaim
so that someone else can claim it and continue from where you left off.
Thank you for your valuable contributions to Open Data Kit!
Collect currently uses
CONNECTIVITY_ACTION
broadcasts to trigger auto-send attempts.Because of #1992, Collect will need to target API 26 by November 2018.
From https://developer.android.com/about/versions/nougat/android-7.0-changes#bg-opt: