WorkManager for CUD operations for an Android Room database based on "persistence" of work? - android-room

I was looking at saving some data to my Room database and was reevaluating as there are some places in my repositories where I am extending AsyncTask (I'm still using Java) and wanted to check on the state of things to see if it was a good time to swap them out. I saw this reference in the Android developer site on Approaches to background work.
All persistent work: You should use WorkManager for all forms of
persistent work. Immediate impersistent work: You should use Kotlin
coroutines for immediate impersistent work. For Java programming
language users, see Threading on Android for recommended options.
Long-running and deferrable impersistent work: You should not use
long-running and deferrable impersistent work. You should instead
complete such tasks through persistent work using WorkManager.
I started using WorkManager for an API which needed to be called, but for which I could not rely on network connectivity. Because I'm using Room, which is persistent, it seems like I should be using WorkManager.
It defines persistent work as:
Persistent work: Remains scheduled through app restarts and device reboots.
A database insert/update/delete is persistent by this definition. Scheduled throws me off a little, as I want it to be immediate, but according to this chart that would still apply.
Is anybody using WorkManager as the mechanism for CUD operations in their repositories and if so, do they have an example?
It would be great to see how this all works in an update fragment. If a single item is selected and I am viewing it in a fragment, when changes are made I would need to update the database using a Worker class and view the data using a LiveData object, correct?
Inserts and returning the id (or object) would be interesting to see as well.

Related

Impact of mongo index creation on spring application deployment

I am working on a Spring application which has an existing mongo collection with a huge amount of data.
I need to create an index on that collection. I will use Mongobee/Mongock like migration framework to create the index.
I want to know that will this index creation affect the duration of Spring application's deployment? What if I set the background property as true for index creation ?
Basically, my desired scenario would be that :-
application's deployment should not affected by the index creation in any way
index creation should happen in background and meanwhile mongo should be able to serve queries on that collection
Please always be sure to include the version that you are running when asking questions like this. There are often important behavioral changes between the versions that are relevant for answers.
Generally speaking, background index creation does what you are looking for. Which is to say that such index builds do not lock the collection and allow the application to continue functioning while the index build is in progress.
That said, the concepts of foreground and background index builds no longer exist. As of 4.2 all index builds are effectively done in the background (ignoring the background argument if provided when issuing the command to create the index). You can read more about that here.
It may also be worth mentioning that you may also choose to build indexes in a rolling manner on a replica set. Clusters in Atlas can choose to use this automatically or you can perform this technique manually otherwise. It is uncommon for this to provide much benefit though, particularly since the new index build method was introduced in version 4.2.
while #user20042973's answer is right and very useful, it only applies to MongoDB.
However, If I am not wrong, you're also worry about Mongock's behaviour and how it may affect your deployment.
What #user20042973 explained above, combined with the use of runner-type: applicationrunner in Mongock, will provide what you are looking for:
Application starts and serves requests, without waiting for Mongock to finish.
MongoDB is available while building the index(for MongoDB version +=4.2)
The deployment of all the instances of your service will start and serve without waiting for the Mongock's lock(not to be confused with MongoDB's lock).
However, it is worth mentioning the following:
You mention the mongock configuration property indexCreation. Well, nothing to do here, it's for the internal Mongock's structure. This is for uses cases where the application doesn't have rights to create the indexes.
If the ChangeUnit fails creating the index and throws an exception, the application is aborted.
If, instead of using runner-type: applicationrunner, you use runner-type: initializingbean, you get the opposite behaviour. Your application won't start until Mongock finishes
runner-type: applicationrunner is the default

VAADIN: Size of UI.access() push queue

I would like to monitor my pushs' to the clients with the famous
UI.access() ... sequence on the server side.
Background is that I have to propagate lots of pushs to my client and I
want to make sure, nothing gets queued up.
I found only client RPCQueue having a size(), but I have no idea if its the correct items searching for now how to access this.
Thanks for any hint.
Gerry
If you want to know the size of the queue of tasks that have been enqueued using UI.access but not yet run, then you can use VaadinSession.getPendingAccessQueue.
This will, however, not give the full picture since it doesn't cover changes that have been applied to the server-side state (i.e. the UI.access task has already been executed) but not yet sent to the client. Those types of changes are tracked in a couple of different places depending on the type of change and the Vaadin version you're using.
For this kind of use case, it might be good to use the built-in beforeClientResponse functionality to apply your own changes as late as possible instead of applying changes eagerly.
With Vaadin versions up to 8, you do this by overriding the beforeClientResponse method in your component or extension class. You need to use markAsDirty() to ensure that beforeClientResponse will eventually be run for that instance.
Wit Vaadin 10 and newer, there's instead a UI.beforeClientResponse to which you give a callback that will be run once at an appropriate time by the framework.

Workflow Waiting Forever

I have a workflow that runs when an entity is created and it creates two other entities and puts them on a queue. It then waits until each entity's status reason is set to done. After which is continues.
Basically two teams will work an order and then it will continue processing after both teams are done.
Most of the time it works. However sometimes it waits forever. I'll re-active and re-resolve the other tasks, but it just never wakes up.
What can I do? The workflows aren't really powerful enough for me to have it poll with a timeout (there are no loops). I'd like to avoid on-change plugins for these other entities to get workflow behavior all scattered about.
Edit:
Restarting the CRM services (not sure which did it, I restarted them all) allowed the workflow to resume. However, I'd still like to know how to make this more reliable.
I had the same problem (and a lot more) with workflows in CRM 2011 and decided not to use them (except for very special purposes).
The main reason is because of their very limited error handling. Another reason is that it is inconvenient to put them under source control. Another reasons are: Worflows cannot run offline and user impersonation is also not supported. For a comparison look here: http://goo.gl/9ht1QJ
Use plugins instead of workflows, then you have full control.
But keep in mind that plugins (unlike workflows) are not designed for long running tasks.
So they have a default max execution time of 120 sec and are not stateful/persisted. But in most cases (and i think also in your case) that is not a problem.
Just change your eventing a little bit:
Implement and register a plugin step for: entity is created and it creates two other entities and puts them on a queue
Implement and register another step: entity's status reason is set to done, query for other entity and check status, if done continue processing
If you really do not want use plugins for you business logic you can consider implementing a plugin which restarts/resumes faulted workflows.
But thats not a very nice solution.

Can I run Android GeoFencing entirely within a background service?

I have an app which needs almost no user interaction, but requires Geofences. Can I run this entirely within a background service?
There will be an Activity when the service is first run. This Activity will start a service and register a BroadcastReceiver for BOOT_COMPLETED, so the service will start at boot. It's unlikely that this Activity will ever be run again.
The service will set an Alarm to go off periodically, which will cause an IntentService to download a list of locations from the network. This IntentService will then set up Geofences around those locations, and create PendingIntents which will fire when the locations are approached. In turn, those PendingIntents will cause another IntentService to take some action.
All this needs to happen in the background, with no user interaction apart from starting the Activity for the first time after installation. Hence, the Activity will not interact with LocationClient or any location services.
I've actually got this set up with proximityAlerts, but wish to move to the new Geofencing API for battery life reasons. However, I have heard that there can be a few problems with using LocationClient from within a service. Specifically, what I've heard (sorry, no references, just hearsay claims):
location client relies on ui availability for error handling
when called from background thread, LocationClient.connect() assumes that it is called from main ui thread (or other thread with event looper), so connection callback is never called, if we call this method from service running in background thread
When I've investigated, I can't see any reason why this would be the case, or why it would stop my doing what I want. I was hoping it would be almost a drop-in replacement for proximityAlerts...
Can anyone shed some light on things here?
The best thing would be to just try it out, right? Your strategy seems sound.
when called from background thread, LocationClient.connect() assumes that it is called from main ui thread (or other thread with event looper), so connection callback is never called, if we call this method from service running in background thread.
I know this to be not true. I have a Service that is started from an Activity, and the connection callback is called.
I dont know about proximity alerts; but I cant seem to find an API to list my GeoFences. I am worried that my database (sqlite) and the actual fences might get out of sync. That is a design flaw in my opinion.
The reason LocationClient needs UI, is that the device may not have Google Play Services installed. Google has deviced a cunning and complex mechanism that allows your app to prompt the user to download it. The whole thing is horrible and awful in my opinion. Its all "what-if what-if" programming.
(They rushed a lot of stuff out the door for google IO 2013. Not all of it are well documented, and some of it seems a bit "rough around the edges").

creating a pojo/ejb with spring 3 that always runs in the background

I have created apps in the past that would have web pages that would call the persistence layer to get some query results or to insert, delete, etc against a db. However, nothing was left running in the background except for the persistence layer. Now I need to develop an app that has an process that is always running in the background, which is waiting for messages to come thru a zeromq messaging system (cannot change this at this point). I am a little lost as to how to setup the object so that it can always be running and yet I can control or query the results from the object.
Is there any tutorial/examples that covers this configuration?
Thanks,
You could use some kind of timer, to start a method every second to look at a specific ressource and process the input taken from that.
If you use Spring than you could have a look at the #Scheduled annotation.
If your input is some kind of java method invokation, than have a look at the java.util.concurrent Package, and concurrent programming at all. -- But be aware of the fact, that there are some restictions one creating own Threads in an EJB environment.

Resources