Start and stop scheduling task in Spring java - java

I develop a simple Spring Boot app that consumes REST and writes to DB.
I tried a #Scheduled annotation to initiate a task to run it periodically.
But the scheduling process starts automaticly, which is not exactly what I want.
I need an ability to start and stop a scheduled task from a web page.
When a user opens a page he must see a status of a process : Running/Stoped.
What is the easy way to implement it? Create a new thread? How to get a status of a process? Save it in db?
Maybe smb has an example of starting and stoping schedduled task from web page?

Try to use ScheduledExecutorService. For example, first of all create a ScheduledExecutorService:
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());
then create a scheduled task:
ScheduledFuture<?> task = scheduledExecutorService.scheduleAtFixedRate(
() -> System.out.println("some task"), 0, 30, TimeUnit.SECONDS);
and when you want to cancel the task, do the following:
task.cancel(true);

Related

Quartz run job again N minutes after completed

I have some repeating quartz jobs that use SimpleScheduleBuilder.repeatMinutelyForever(60). Lets say the job initially gets scheduled at 10:02am and runs for 5 minutes completing at 10:07am.
Right now it is getting scheduled to run again at 11:02am but I want it to run again 60 minutes after completing so it should be scheduled at 11:07am instead.
Is there any way to change the scheduling to do this? Or should I use a one time job that creates a new job each time it completes?
Use TriggerListener - see here for some examples in Quartz cookbook.
You will override triggerComplete and in there you will add your rescheduling code:
public void triggerComplete(Trigger trigger, JobExecutionContext context, CompletedExecutionInstruction triggerInstructionCode) {
// check here the triggerInstructionCode value and reschedule your job
super.triggerComplete(trigger, context, triggerInstructionCode);
}
Example for registering a TriggerListener with the scheduler to listen to a specific trigger:
scheduler.getListenerManager().addTriggerListener(myTriggerListener, keyEquals(triggerKey("myTriggerName", "myTriggerGroup")));
See also this answer.

Play Framework - Get scheduled task status

I'm working with Java Play Framework (2.3.6) and have some problems handeling scheduled tasks. Sometimes some of my recurring tasks crash with an exception. So I want to create a website to check the status of my scheduling tasks to have a quick view, if each tasks still runs without problems.
I know, I have also to check the exceptions but the website would be a nice controlling tool.
So I have some scheduled tasks like this one:
ExecutionContext dispatcher = Akka.system().dispatcher();
FiniteDuration timeNow = Duration.create(0, TimeUnit.SECONDS);
FiniteDuration time1m = Duration.create(1, TimeUnit.MINUTES);
Recorder recorderTask = new Recorder(); // implements Runnable
Akka.system().scheduler().schedule(timeNow, time1m, recorderTask, dispatcher);
Now, is there any possibility to check the status of my task (like it's alive)?
Thanks for your help!

Recursive function call with time delay

I have a web application, I need to run a backgroung process which will hit a web-service, after getting the response it will wait for few seconds(say 30) then again hit the service. The response data can vary from very less to very large, so i dont want to call the processagain untill i am finished with processing of data. So, its a recursive call with a time delay. How i intend to do is:
Add a ContextListener to web app.
On contextIntialized() method , call invokeWebService() i.e. arbitary method to hit web service.
invokeWebService will look like:
invokeWebService()
{
//make request
//hit service
//get response
//process response
timeDelayInSeconds(30);
//recursive call
invokeWebService();
}
Pls. suggest whether I am doing it right. Or go with threads or schedulers. Pls. answer with sample codes.
You could use a ScheduledExecutorService, which is part of the standard JDK since 1.5:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Runnable r = new Runnable() {
#Override
public void run() {
invokeWebService();
}
};
scheduler.scheduleAtFixedRate(r, 0, 30, TimeUnit.SECONDS);
It is not recursive but repeated. You have two choice here:
Use a Timer and a TimerTask with scheduleAtFixedRate
Use Quartz with a repeated schedule.
In quartz, you can create a repeated schedule with this code:
TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(30))
.build()
From what I am getting, waiting sort of implies hanging, which I do not really think is a good idea. I would recommend you use something such as Quartz and run your method at whatever interval you wish.
Quartz is a full-featured, open source job scheduling service that can
be integrated with, or used along side virtually any Java EE or Java
SE application
Tutorials can be accessed here.
As stated in here you can do something like so:
JobDetail existingJobDetail = sched.getJobDetail(jobName, jobGroup);
if (existingJobDetail != null) {
List<JobExecutionContext> currentlyExecutingJobs = (List<JobExecutionContext>) sched.getCurrentlyExecutingJobs();
for (JobExecutionContext jec : currentlyExecutingJobs) {
if(existingJobDetail.equals(jec.getJobDetail())) {
//String message = jobName + " is already running.";
//log.info(message);
//throw new JobExecutionException(message,false);
}
}
//sched.deleteJob(jobName, jobGroup); if you want to delete the scheduled but not-currently-running job
}

How to complete a Job when user closes Eclipse application

I use org.eclipse.core.runtime.jobs.Job to execute stored procedure which deletes data and to update user interface according to the new data. Thus it is important that this job will be completed even if user closes eclipse application.
final Job execStoredProcJob = new Job(taskName) {
protected IStatus run(IProgressMonitor monitor) {
monitor.beginTask(taskName,
// execute stored procedure
// update user interface
monitor.done();
return Status.OK_STATUS;
}
};
execStoredProcJob.schedule();
When I close eclipse app while the Job still running it seems to kill the Job. How to complete the job after user has closed eclipse app? Is it possible?
I think you might want to take a look at scheduling rules
http://www.eclipse.org/articles/Article-Concurrency/jobs-api.html
execStoredProcJob.setRule([Workspace root]);
execStoredProcJob.schedule();
[Workspace root] can be attained like project.getWorkspace().getRoot() if you have a reference to your project.
That will block all jobs that require the same rule. The shutdown job is one of them..
It's also possible to:
IWorkspace myWorkspace = org.eclipse.core.resources.ResourcesPlugin.getWorkspace();
Then use:
myWorkspace.getRoot();
An alternative to scheduling rules is to add code in WorkbenchAdvisor.preShutdown() that will join any outstanding job you have...

What is the correct way to restart a ScheduledExecutorService scheduled task?

I have a scheduled task (running in fixed delay execution), started like this:
executoreService.scheduleWithFixedDelay(repeatingThread, 0, numOfSeconds, TimeUnit.SECONDS);
On every start of cycle, I check for a change in a settings file, and then I want to restart the task. The settings file also contains length of the interval (numOfSeconds in the above code).
Currently, I am using the following code to restart the task:
executoreService.shutdownNow();
try {
while(!executoreService.awaitTermination(5, TimeUnit.SECONDS)){
logger.debug("awaiting termintation");
}
} catch (InterruptedException e) {
logger.debug("interrupted, continuing", e);
}
// initialize startup parameters
init();
// start the main scheduled timer
executoreService.scheduleWithFixedDelay(repeatingThread, 0, numOfSeconds, TimeUnit.SECONDS);
I'm not sure about these API calls. What is the recommended way to restart the task (possibly with a new delay)?
No, you don't want to or need to shut down the whole service just to modify one task. Instead use the ScheduledFuture object you get from the service to cancel the task, and then schedule a new one.
ScheduledFuture<?> future = executorService.scheduleWithFixedDelay(repeatingThread, 0, numOfSeconds, TimeUnit.SECONDS);
...
// to cancel it:
future.cancel(true);
// then schedule again
Alternatively, why not just update state in whatever repeatingThread is with new settings or parameters? it doesn't even need to be rescheduled, if you don't need a new delay.

Categories