Spring scheduler (quartz) how to pauseAll schedulers and reschedule them before resumeAll - spring

The need is such clear that first I pauseAll schedulers and before resumeAll I want to reschedule jobs (I mean change the trigger expressions) and make them resume with THE NEW trigger expressions not the former ones.
Is it possible rescheduling a scheduler while it is paused? In other words is it ok by doing the following?
scheduler.pauseAll(); // pause first
scheduler.rescheduleJob(...); // reschedule while it is paused??
scheduler.resumeAll(); // resume All with the new job-trigger expressions as above
(I cannot test exact scenario because of restrictions about the project structure by now, I need time for build test and adapt to the project)
Thanks in advance.

I figured out today that it is possible to reschedule jobs even while scheduler is in pause state. Thus, I made it done by the following peace of code as I mentioned above:
scheduler.pauseAll(); // pause first
scheduler.rescheduleJob(...); // reschedule while it is paused
scheduler.resumeAll(); // resume All

Related

How to Stop the Spring Batch Job Execution Immediately or forcefully?

I have a spring batch job and it has 3 steps, the 3rd step has some tasklet as below. Now when we try to stop the job using,
jobOperator.stop(id);
it sends the STOP signal when STEP 3 is in progress and interrupts only when all the tasklet in the STEP 3 is completed. Let's say it has 10 tasks, although we sent the stop signal when it was STEP 3 and Task 1 in progress - it does not stop there. It finishes all the 10 tasks and then marks this STEP 3 status as COMPLETED. Is there any way we can stop step 3 while processing the first task? I did see the spring batch documentation and did not find much. Below is the sample code.
Job:
#Bean(JobConstants.CONTENT_UPGRADE_JOB)
public Job upgradeContentJob() {
Tasklet tasklet = context.getBean("incremental_deploy_tasklet", Tasklet.class);
SimpleJobBuilder jobBuilder = jobBuilderFactory.get(JobConstants.CONTENT_UPGRADE_JOB)
.listener(upgradeJobResultListener())
.start(initContent())
.next(stepBuilderFactory.get("create_snapshot_tasklet").tasklet(createSnapshotTasklet()).build())
.next(stepBuilderFactory.get("incremental_deploy_tasklet").tasklet(tasklet).build());
return jobBuilder.build();
}
Tasks:
packCompositionMap.put(incremental_content_deploy, Arrays.asList(
create_security_actions ,slice_content, upgrade_appmodule,
application_refresh,
install_reset_roles_bar, restore_reset_roles_bar,
populate_roles, add_roles,
replay_security_actions,
create_adw_connection,
apply_system_extensions,
replay_system_steps,
assign_service_admin
));
Here STOP signal for the id is sent when "incremental_deploy_tasklet" is just initiated and "create_security_actions" task is picked from the array list but the problem is it does not stops but completes all the item task in the array and then marks the status for this "incremental_deploy_tasklet" step as STOPPED and then overall status for this job is also marked as STOPPED.
What I am looking for is help on to STOP and interrupt at this "create_security_actions" task itself. Any help or input is appreciated, Thank you
After reading multiple docs and trying it- found that we cannot terminate the thread immediately. The control should come back to the framework.
The shutdown is not immediate, since there is no way to force an immediate shutdown, especially if the execution is currently in developer code that the framework has no control over, such as a business service. However, as soon as control is returned back to the framework, it will set the status of the current StepExecution to BatchStatus.STOPPED, save it, then do the same for the JobExecution before finishing.
Thank you.

what is the best way to get notified when a task finishes, in F#?

I have a pool of tasks and I am trying to figure out the best way to be notified, through an event, when one is finished.
Since the tasks are quite varied, I don't want to add a piece of code inside the task itself since that would mean putting it in several places. These are long running tasks, I'm not waiting for them to complete anywhere, they're just getting started, do their work (minutes to days) and then they finish.
The ugly-but-could-work solution is to wrap each work task into another task that awaits for the work task to be complete and then sends an event, but I'm hoping there would be something more elegant.
In a comment you explained that you're starting your tasks like this:
Async.StartAsTask (runner.Start(), TaskCreationOptions.LongRunning, cancellationSource.Token)
Instead of doing that, start them like this:
startMyTask runner cancellationSource (fun() -> printfn "Task completed!")
Where:
let startMyTask (runner: RunnerType) (s: CancellationTokenSource) onDone =
let wrapper = async {
do! runner.Start()
onDone()
}
Async.StartAsTask (wrapper, TaskCreationOptions.LongRunning, s.Token)

How to delete the dispatched block using GCD

I have this code:
_myQueue = dispatch_queue_create("com.myapp", DISPATCH_QUEUE_SERIAL);
_mainQueue = dispatch_get_main_queue();
and lot of this block that require some seconds (or minutes)
dispatch_async(_myQueue,
^{
if(canRun){
dispatch_async(_mainQueue,^{/* updating interface here */});
// code here
}
});
My app have a "Stop" button to try stopping all job, and the BOOL "canRun" help me to execute all blocks w/o do nothing.....but always I have to wait the completition of each block until the queue come 0.
Is there any way to instantly "clean" the queue istead doing that?
The aim is to stop processes and to start over without closing and reopening the application.
This project works under ARC.
You can cancel them if you take a few extra steps to creat a dispatch_source object and keep a reference to it.
Review this for starters
https://developer.apple.com/library/mac/documentation/Performance/Reference/GCD_libdispatch_Ref/index.html
There are functions to pause, resume and cancel.

Spring #Async cancel and start?

I have a spring MVC app where a user can kick off a Report generation via button click. This process could take few minutes ~ 10-20 mins.
I use springs #Async annotation around the service call so that report generation happens asynchronously. While I pop a message to user indicating job is currently running.
Now What I want to do is, if another user (Admin) can kick off Report generation via the button which should cancel/stop currently running #Async task and restart the new task.
To do this, I call the
.. ..
future = getCurrentTask(id); // returns the current task for given report id
if (!future.isDone())
future.cancel(true);
service.generateReport(id);
How can make it so that "service.generateReport" waits while the future cancel task kills all the running threads?
According to the documentation, after i call future.cancel(true), isDone will return true as well as isCancelled will return true. So there is no way of knowing the job is actually cancelled.
I can only start new report generation when old one is cancelled or completed so that it would not dirty data.
From documentation about cancel() method,
Subsequent calls to isCancelled() will always return true if this method returned true
Try this.
future = getCurrentTask(id); // returns the current task for given report id
if (!future.isDone()){
boolean terminatedImmediately=future.cancel(true);
if(terminatedImmediately)
service.generateReport(id);
else
//Inform user existing job couldn't be stopped.And to try again later
}
Assuming the code above runs in thread A, and your recently cancelled report is running in thread B, then you need thread A to stop before service.generateReport(id) and wait until thread B is completes / cancelled.
One approach to achieve this is to use Semaphore. Assuming there can be only 1 report running concurrently, first create a semaphore object acccessible by all threads (normally on the report runner service class)
Semaphore semaphore = new Semaphore(1);
At any point on your code where you need to run the report, call the acquire() method. This method will block until a permit is available. Similarly when the report execution is finished / cancelled, make sure release() is called. Release method will put the permit back and wakes up other waiting thread.
semaphore.acquire();
// run report..
semaphore.release();

Troubles trying to start two asynchronous tasks.

I want to start two Async Tasks but the second will not start until the first has completed.
From what I've googled, people usually suggest this approach:
new MyAsyncTask().execute(params);
new MyAsyncTask().execute(params);
However, I need to instantiate them separately and also keep the handles of the task's (to pass messages for example). Therefore, I SORT OF do this:
onStart()
{
taskA = new MyAsyncTask(paramsA);
taskB = new MyAsyncTask(paramsB);
}
onButtonPress()
{
taskA.execute();
taskB.execute();
}
Edit:
I've noticed that taskB does not actually start executing until taskA completes (which runs a tcp/ip server so it takes a long time). I cannot figure out why. Any thoughts or comments ?
The short answer is that, depending on your version of Android, all AsyncTask subclasses may be using the same thread, so you can only do one at a time. There are two ways around this:
Use Runnable instead of AsyncTask
Replace one call to execute with executeOnExecutor(Executor.THREAD_POOL_EXECUTOR, params)
Clearly, try #2 first - it's less of a code change. But if that doesn't work pretty quickly, I'd switch to #1. In that case, you don't have to worry about how Android might change in the future.
If you want more details about the threading model for AsyncTask, have a look at the Android doc entry.

Resources