Programmatically stop a PlayFramework Job - asynchronous

I am trying to programmatically stop a running Job in PlayFramework. When a Job is run, I save the 'Promise' object that it returns when it's started. This object has a 'cancel' method that SHOULD cancel a scheduled job OR stop an existing job, however it doesn't seem to do anything.
What other way is there to stop a running Job?

I think you need to implement well-ordered cancellation yourself. cancel won't just end the thread's execution as this may cause undesired results. The solution is similar too how Thread.stop() is deprecated and Thread.interrupt() should be used instead.
Check if the job got cancelled at occasion. If you are running heavy calculation in a loop, check if it still should continue running at the beginning. You can even return partial results this way.

Related

Xamarin android Worker

I have old xamarin android jobintentservice I'm replacing to support android 12.0.
I now inherit Worker instead of JobIntentService, and use WorkManager to enqueue its job.
Couple of questions:
Is there a way use await inside DoWork override method?
Is it better to inherit ListenableWorker instead in order to use await? Do I lose
anything if I switch to it?
If I Task.Factory.StartNew(LongRunning) from Worker's DoWork, and immediately that follow with return success result, will my long running task run to completion, or all work associated will be terminated?
I think you can know more about WorkManager first.
From document Schedule tasks with WorkManager we know that:
WorkManager is the recommended solution for persistent work. Work is persistent when it remains scheduled through app restarts and system reboots. Because most background processing is best accomplished through persistent work, WorkManager is the primary recommended API for background processing.
WorkManager handles three types of persistent work:
Immediate: Tasks that must begin immediately and complete soon. May
be expedited.
Long Running: Tasks which might run for longer, potentially longer
than 10 minutes.
Deferrable: Scheduled tasks that start at a later time and can run
periodically.
And from the Work chaining of Features,we know
For complex related work, chain individual work tasks together using an intuitive interface that allows you to control which pieces run sequentially and which run in parallel.
WorkManager.getInstance(...)
.beginWith(Arrays.asList(workA, workB))
.then(workC)
.enqueue();
For each work task, you can define input and output data for that work. When chaining work together, WorkManager automatically passes output data from one work task to the next.
Note:
If you still have any problem, get back to me.

How does Dart know when a program has finished in relation to asynchronous code

I've been learning about the event loop and asynchronous code execution in Dart. Here is how I understand it works:
Dart runs the synchronous code in main first.
Any completed futures are put on the event queue and get run in FIFO order.
Any microtask events get handled before the next event in the event queue.
The part I'm missing is what about an uncompleted future? What if you have something like this:
final myFuture = Future<int>.delayed(
Duration(seconds: 1),
() => 42,
);
In that one second delay, say all the synchronous code, microtasks, and event queue tasks have completed. How does Dart know it shouldn't terminate the program? Is there a little holder somewhere for uncompleted futures?
I don't know if my title accurately reflects what I'm asking. Feel free it edit it.
The life-time of a Dart program depends on where it runs.
Code running in a browser doesn't stop unless the page goes away. Web pages won't end like a script or application does.
So, what you are likely really asking is when a program run on the Dart VM stops. The short answer is: When there is nothing more to do (in the main isolate).
The program ends when the main isolate is done. That's the first isolate to run. If you start new isolates, they won't keep the program alive by themselves, so make sure to keep the main isolate alive until your program is done.
An isolate is done when there is nothing more to do, and there is no good way to receive instructions to do something more.
That means:
There is no code running.
The event and microtask queues are empty.
There are no scheduled timers or outstanding I/O operations (you can think of these as being kept in separate internal work queues, and when they have a result ready, they trigger events in the main event queue. These queues also need to be empty for the program to be done).
There are no open receive ports (ReceivePort, RawReceivePort).
That means that there is nothing to do, and no open communication channels to receive messages on.
The traditional way to keep an isolate alive, perhaps because the real computation is being done in a different isolate, is to create a ReceivePort, and then close it when everything else is done (which you'd probably notify them about by sending an event to that receive-port).

What is the recommended action on receving ChangeFeedObserverCloseReason.ObserverError?

My ChangeFeedProcessor's IChangeFeedObserver.CloseAsync callback was invoked with ChangeFeedObserverCloseReason as "ObserverError". So, far I have seen this error only once and I am not sure how to repro it. What causes this error? Is there a way to diagnose this more? Is there any recommended action that one should take after receiving this error?
From your question, I understand you are using Change Feed Processor.
That Close reason is provided when the code in your ProcessChangesAsync implementation throws an unhandled exception.
Basically, if that happens, it means your code had an error processing the changes so:
The Observer is closed, releasing the Lease
The lease becomes available to be picked by any Host instance
The lease gets picked up by a Host, an Observer started, the same batch of changes gets sent to be processed
If the nature of your error was transient, then this time it will work (hopefully). If its not transient, then you will again face an ObserverError.
As a rule of thumb, always try to manage your exceptions if possible, if not, it will be treated as a temporary scenario and will get eventually retried as I described.
Also please next time give more context, describe which libraries and versions you are using and provide some related code. It will help a lot understanding and diagnosing.

activiti taskService complete fails when executed concurrently

Hi I am facing a strange situation where I am trying to set a set of tasks as complete all concurrently.
The first one goes through and second one goes through sometimes (rarely) but mostly doesnt go through.
When I do these individually they work.
Something to do with database locking I feel. Is there some workaround or code for executing task and variable updates concurrently ?
Do they belong to the same process instance?
And yes, there will be a db locking mechanism in place, because when you complete each task a process instance will need to move forward.
Can you please clarify what are you trying to solve? what is your business scenario?
Cheers
Activiti uses pre-emptive locking and this can cause problems for parallel tasks.
Typically if you use the "exclusive" flag the problems go away (https://www.activiti.org/userguide/#exclusiveJobs).
Keep in mind that jobs never actually run in parallel, the job engine selects jobs to run and if there are multiple they will be run sequentially (which appears to be parallel to the user).

Encountered activationStatus has been modified externally when publishing

I'm doing an update for multiple nodes and then a batch publish (a lot of data) using the command "Activate" to publish the nodes programmatically but sometimes I don't know why I will get an error sometimes. It only happened for few times so far so I find it hard to figure out what's the one causing the issue.
Here is the error thrown.
Caused by: org.apache.jackrabbit.core.state.StaleItemStateException: 8b3ce2d4-eb7b-4838-901c-413aa9eeee84/{http://www.magnolia.info/jcr/mgnl}activationStatus has been modified externally
at org.apache.jackrabbit.core.ItemSaveOperation.removeTransientItems(ItemSaveOperation.java:723)
at org.apache.jackrabbit.core.ItemSaveOperation.perform(ItemSaveOperation.java:228)
Have anyone encountered a similar issue? Or any idea where to look at this issue?
Thanks! :)
Basically update operation internally cause Magnolia to modify the activation state (which is correct). When this operation is ongoing the update operation is taking over and attempting to change the state. In this case if you are unlucky you might hit the exception you got. Reasoning being is that those commands run async but touch the same nodes.
Potential Solution:
1) You may simply give some time for the first operation to complete and execute the second one after.
2) This needs some development effort but here we go:
You may use LockManager to lock the nodes being used by the first operation and unlock it when the operation is done completely. Second operation meanwhile will check if the nodes are locked and if yes will not continue but wait till its unlocked from the first process.

Resources