Scheduling a task periodically in an android app using WorkManager(Coroutine Worker) - job-scheduling

I'm trying to run a task periodically every 12 hours, I'v used Work Manager and followed their documentation. The task is running periodically well as long as the user is actually using the app.
But if i close the app, or even just let my phone be idle for a while, it seems like the task stops working.
I searched for this problem on google, and came across posts such as this post, which i think explains the behaviour on my phone.
From my understanding, this problem is not related to work manager, but to all frameworks who will try to run background tasks?
Is there a way to still periodically run tasks on most devices or is WorkManager is still the way to go?
Thanks!

Please check this:
https://developer.android.com/topic/libraries/architecture/workmanager/how-to/debugging#use-alb-shell0dumpsys-jobscheduler
Required constraints: TIMING_DELAY CONNECTIVITY [0x90000000]
Satisfied constraints: DEVICE_NOT_DOZING BACKGROUND_NOT_RESTRICTED WITHIN_QUOTA [0x3400000]
Unsatisfied constraints: TIMING_DELAY CONNECTIVITY [0x90000000]
Minimum latency: +1h29m59s687ms
Run time: earliest=+38m29s834ms, latest=none, original latest=none
The periodic work is not exactly Periodic. You have different Constraints:
Explicit - you set them.
Implicit - set by the system related to Battery optimization. You should save the battery and also Internet usage.
When you have a "periodic work" you actually have an explicit constraint called:
TIMING_DELAY. But when the time is passed it does not mean that the work will start. It means that this constraint is satisfied and if and only all the other constraints are Satisfied - then the work will start.
And for example, you have your work with a "period" of 12 hours, but you wait an extra 4 hours for the other Constraints - you will have a period of 16 hours.
And after the work is finished - WorkManager will create a completely new job in the JobScheduler with TIMING_DELAY again - 12 hours. It will not account for the extra 4 hours. So you can't imagine something like:
I have 5 days so it means - 10 executions. It might be only 4 or 5 executions.
You can improve this by asking the user to exempt you from battery optimization:
https://developer.android.com/training/monitoring-device-state/doze-standby#support_for_other_use_cases
If you need to be really exact - you need to use AlarmManager, but mostly the idea of all of this is for the battery to be saved so it is not only about what the devs need, but also what the user needs.

Related

JMeter - How to execute a thread group every 10 minutes ( What is the best practice ? )

I have a situation where an API is called by 500 users/threads every 10 minutes.
I have created a jmeter script for this. It takes around 4 to 5 minutes to get response for all the 500 threads.
Now I have created a batch file to execute this jmx file. This batch file is then called every 10 minutes using task scheduler in windows.
I am not sure whether this is the best approach.
Have read about test action sampler / Timers / Think time etc.
Please can someone advise which is recommended in my case.
My requirement is to trigger the thread group every 10 minutes irrespective of how long the the previous run took.
According to Linus Torvalds
If it compiles, it is good; if it boots up, it is perfect
Given your approach works fine for your use case you should be good to go.
Personally I would be interested in test results as well (not sure how you're handling them), perhaps a better idea would be putting your script under orchestration of a Continuous Integration server like Jenkins, it provides flexible options on triggering the jobs (including scheduling) and you will be able to get some statistics, trends and conditionally mark your tests as passed or failed basing on the response time using Performance Plugin

Spring and scheduled tasks on different Data Centers

I have one spring scheduler , which I will be deploying in 2 different data center.
My data centers will be in active and passive mode. I am looking for a mechanism where passive data center scheduler start working where that data center become active .
We can do it using manually changing some configurations to true/false but , I am looking for a automated process.
-Initial state:
Data center A active - Scheduler M is running.
Data center B passive - Scheduler M is turned off.
-May be after 3 days.
Data center A passive - Scheduler M turned off.
Data center B active - Scheduler M is starting
I don't know your business requirements but unless you want multiple instances running but only one active, the purpose you will have a load balancer would be to spread the load to multiple instances of the same application rather to stick with only one instance.
Anyway I think an easy way of doing this without using a very sophisticated mechanism (coming with a lot of complexity depending where you run your application) would be this:
Have shared location such as a semaphore table in your database storing the ID of the application instance owning the scheduler process
Have a timeout set for each task. Say if the scheduler is supposed to run every two minutes set the timeout to two minutes.
Have your schedulers always kick off on all application instances
Once the tasks kicks off first check if it is the one owning the processing. If yes do the work, if not go at point 7.
After doing the work record the time stamp of the task completion in the semaphore table
Wait for the time to pass for the next kick off
If not the one owning the processing check when the task last run in the semaphore table. If the time since last run is greater than the timeout set for that process take the ownership of the process (recording your application instance id in the semaphore table)
We applied this and it ran very well with one of our applications. In reality it was much more complex than explained above as we had a lot of application instances and we had to avoid starting an ownership battle between them. To address this we put in place a "Permission to process request" concept so no matter how many instances wanted to take control it was only one which was granted.
For another application with similar requirements we used a much much easier way to achieve this but the price we paid was some extra learning curve in using ILock from Hazelcast IMGB framework. That is really very easy but keep in mind the Hazelcat community edition comes with absolutely no security and paying for a Hazelcast license just to achieve this may be a bit of expense.
Again all depends on you use case, for us the semaphore table was good enough in first scenario but prove bad in the second one as the multiple processes trying to update the same table at the same time ended up with a lot of database contention which took us to Hazelcast.
Other ideas would be a custom health check implementation that could trigger activating one scheduler or the other depending of response received.
Hope that helps, just ideas from our experience. Good luck.

Windows Phone 8 scheduled agent update custom interval (more than 30 minutes)

There are couple of apps at the Windows Phone Store which are automatically updating phone lock screen by a custom interval, lets say 1, 2, 4 or more hours.
I did some search over internet to find some articles or best practice to implement custom update interval, which is bigger than 30 minutes but without any result.
Maybe you know some code snippets or reference on articles ?
Thanks in advance!
As you have already found, the periodic agents are invoked once every 30 mins. However, you can simply do nothing until your desired update period has passed then execute your update.
You already have access to your app's isolated storage from within your background agent. You can simply store a counter in some file to track the time that has passed and once it meets your requirement you can execute your update and reset the counter.

Oracle Text: update while index is being synchronized

I have a complex context index that gets synchronized nightly. The process takes some 10 minutes, and any updates to this table that touch the index column during synchronization period result in ORA-29861: domain index is marked LOADING/FAILED/UNUSABLE exception - what can I do about it?
I don't think you can do anything else while that thing is synchronizing. If the index update is unavoidable then you'll need to find a way to queue up the requests and retry say every 15 minutes till it/they go through. I would suggest a limit of 3 tries until it goes through or fail gracefully. I make the suggestion of 3 times because if it is supposed to take 10 minutes and it doesn't work in 45 minutes, you have bigger fish to fry I would think. Might as well make it fail gracefully than endlessly repeating on a broken system. Hopefully you don't have so many attempted hits to the database during that period that you end up with a big queue. You could also see if you can synchronize your app with the times your infra people set up for updating indexes. So that you block these transactions at the same time. I don't know how big your organization is or what the systems are like (if you are running Oracle you guys have enough money for something sizable). That means you might have scheduling apps that might help? In any case, unless the DBAs stop doing these updates, you'll have to wait till they finish I would think.

how to implement custom cloud worker

I am designing a cloud app and need a worker process which scours my database looking for work, and then performs it.
Most of the info I seem to find on the subject of background tasks in the cloud involves some kind of scheduler and/or queuing system.
What I have doesn't quite fit into the "run this task every 5 minutes" or "add this to the queue to be executed later" models. I think the main difference to my problem is that the workers themselves find work to do, rather than being assigned it by a periodic scheduler or an external process that generates work.
What I have is basically a giant table where each entry has three fields:
job: a small task to be performed, lets say it gets the last message from a twitter account and stores it in the database
the interval at which to perform that job: say every 5 minutes, N.B. the interval is arbitrary and different for each entry in the table
the last date when the job was performed
The way I would implement this is to have a worker which has an infinite loop. When it enters the loop, it scours the database a)looking for items whose date + interval < currentTime, b)when it finds one, it sets date = currentTime, and c)then executes the job. If there is no work ATM, it sleep for a few seconds, then tries again.
I will have many parallel workers scouring the database simultaneously, which is why I do b) first and then c) in the paragraph above. Since there are parallel workers, action a) and b) are atomic operations on the database to prevent work being duplicated. If the worker crashes after a) and b), but before it manages to finish the work, it's no big deal, and the workers can just do it at the next interval; reason for this is that the work is not performed in a time-invariant system so a backlog scenario of failed jobs has no benefit as the tasks have to be performed at their exact intervals, so it's better to skip 1 interval than to have uneven intervals between which the tasks were executed.
My question is whether that is a reasonable implementation strategy? If so, how do I bring this process to life on the cloud (I am using Heroku, but may switch to EC2 in the future)? I still haven't written any code so I would welcome other suggestions (maybe I misunderstood the use cases/applications for queue systems).
This sounds so close to using something like a scheduled job that you might as well tread the well beaten path and do it the more conventional way. There's no reason why you can't schedule a job to run once every few seconds.
However, this idea of looking for work sounds dodgy. What happens if two workers find the same task to run at the same time for instance? Also, are there not triggers in the application which can indicate that work needs doing? It seems strange that you have code 'looking for work'.
You can go a very long way with simple periodic background tasks, so I would exhaust all possibilities in that area before rolling your own.

Resources