#Scheduled annotation Spring - java

I am using Spring 3 annotation #Scheduled to create scheduled jobs on server. But i am confused about the parameters(cron, fixedDelay ,fixedRate) of #Scheduled annotation. Please explain the difference between these parameter and the situations in which I can use these parameters.

I believe the difference among different options are made clear here. It depends on how you need to execute the task:
fixedRate makes Spring run the task on periodic intervals even if the last invocation may be still running.
fixedDelay specifically controls the next execution time when the last execution finishes.
cron is a feature originating from Unix cron utility and has various options based on your requirements.

cron : A cron-like expression, extending the usual UN*X definition to include triggers on the second as well as minute, hour, day of month, month and day of week.
fixedDelay : Execute the annotated method with a fixed period between the end of the last invocation and the start of the next.
fixedRate : Execute the annotated method with a fixed period between invocations.
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html

Related

#Scheduled and scheduledExecutorService.scheduleWithFixedRate in java

What is the difference between #Scheduled annotation in Spring and using ScheduledExecutorService's scheduleWithFixedDelay method in Springboot? With the help of code, can someone demonstrate the exact usage difference and when to opt for which one?
Please have a look at https://www.baeldung.com/spring-task-scheduler . The #Scheduled is a generic implementation, which you can extend and configure for your needs. While the scheduleWithFixedDelay is a specific implementation that you can directly use. Ideally, it is fine to use either of them, but if your functionality is not supposed to change, it is better to use the implementation (I mean scheduleWithFixedDelay)
#Scheduled without a cron expression, fixeddelay or fixedrate is nothing. How can it know the interval, if not specified?
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html
fixedDelay ensures that there is always n seconds duration
if first invocation is at 9:00:00 and fixedDelay = 10minutes, process
takes 15 seconds to complete, then next cycle start = 09:10:15

Java EE6 Schedule Range

I'm required to have a schedule that runs every 5 minutes from 10 am to 5:45pm, how do I do this with the #Schedule annotation?
So far, I'm limited to the #Schedule(hour=10-18;minute=*/5), but they insist I should have it until 5:45pm not 6pm.
As clearly stated in the documentation for #Schedule and #Schedules, you need to have two #Schedule annotations if you run two schedules - even if you don't like that fact.
Due to the cron-like limitations of having ranges only within individual elements (hours, minutes, seconds...), it's simply not posible to give that additional information of skipping the last two executions at *:50 and *:55 only at 5pm.
That said, you'd probably end up with something like
#Schedules({
#Schedule(hour="10-16" minute="*/5"),
#Schedule(hour="17" minute="0,5,10,15,20,25,30,35,40,45")
})
As you end up with schedule information into you sourcecode that way (even if it's in the form of an annotation) you could just as well run every five minutes and immediately return from the method if called after 5:49pm

Spring Boot - check if target date is reached for objects

I don't know if it's a real question or not... But i'd like to know how some of you will approach this...
I have a Spring Boot application.
Then I have a Interruttore.class, which has, among others this field timeoutDatewhich is a Date.
In the app, various instances of this class are used. The timeoutDate field can be updated, for every single object, by various factors. I need to know when the actual date reaches the timeutDate.
In a very simple (and not optimized) way i would have created a #Scheduled task, but the delay will be too short and i don't like it, how can i do?
In a very simple (and not optimized) way i would have created a
#Scheduled task, but the delay will be too short and i don't like it,
how can i do?
Why too short ?
You can use the delay you wish.
#Scheduled(fixedDelay=50000) // 50 secs
#Scheduled(fixedDelay=1000) // 1 secs
Look at the documentation for Spring's various task scheduling APIs: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html
You have plenty of choices. I think the "not optimised" idea you might have is to schedule a repeating task which searches your beans to find the expired ones. That would indeed be inefficient for large numbers of beans.
You could simply create a scheduled task for each bean with a timeoutDate, created at the same time as that bean, and when its timeoutdate is updated (Spring AOP could help with this).
Alternatively you could keep a list of beans, sorted by timeout date. Schedule a task for the time of the earliest expiry. It reaps that bean and any others who's time is past, then schedules a new task for the time of the next expiry.
If you do this, you need to make sure that:
- it handles new objects added to the list (perhaps with an expiry date earlier than the currently scheduled cull)
- it handles the case where an object is removed for a reason other than a timeout
(Unless neither of those things can happen -- in which case don't worry about it!)
You can use Quartz or Jesque(redis). Whatever task needs to be executed, you can schedule that task at that time.
If this time value can be updated anytime, you can cancel(unschedule) the previously scheduled task(using task identifiers or keys) and reschedule it with the updated time.

is it ok that two spring batch job overlaps?

Suppose I have a spring job run every 5 minute, usually the job will take about one minute to complete, but if something goes wrong the job will last more than 5 minute. Before last job finished , another job will start. So, the two jobs will interfere with each other?
ps: I use the spring schedule annotation to schedule jobs.
You can control this behavior. If you want to leave a fixed amount of time between the end of one job and the start of the next, use the fixedDelay http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html#fixedDelay--.
If you use the fixedRate, then jobs may overlap. Whether that's "ok" depends on what your job does. But you can prevent this from happening with fixedDelay if you want.

Quartz job tunning

hello there is something i've realized with quartz when working.Say a cron is set to wake up every 2min with the expression 0 0/2 * * * ? .
When you run the project at say 13:10:30, the first action happens at 13:12:00 and the second 13:14:00 and every 2min 0 second for the rest. Obviously between the startup of the project and the first occurence of the action there have been 1mn:30s only.
Is there a way to for the first occurrence to respect the 2min no matter which at seconds the project starts?
Cron jobs are configured in Quartz using the CronTrigger class. The alternative is to use SimpleTrigger, which you can construct using fixed delay intervals. SimpleTrigger has various constructors, allowing you to specify the start time, end time, number of repeats, repeat interval, and so on.
Having said that, I'd recommend against using Quartz for this kind of scheduling, and use java.util.concurrent.Executors.newScheduledThreadPool(). It's much easier than Quartz when it comes to simple repeating tasks.
Quartz may use cron for the scheduling, which is based on date and time, not duration. This means that the cron expression you define is directly related to the current time on the machine, not on when the application started.
I am not aware of a Quartz configuration that will help you to solve your problem. However, a solution is to create your own Thread, which started during the launch of your application and that basically waits 2 minutes before calling a method:
while (running) {
Thread.sleep(1000 * 120);
doStuff();
}

Categories