Why this cron pattern doesn't match/run every 37 seconds? - spring

I have a Spring app with this property:
cobra.tarifas.intervaloEntreCobrancas =*/37 * * * * *
And this is where it's used:
#Scheduled(cron = "${cobra.tarifas.intervaloEntreCobrancas}")
public void cobraTarifaDMaisZero() {
int number = new Random().nextInt();
System.out.println("started " + number + " at " + LocalTime.now().withNano(0));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("finished " + number + " at " + LocalTime.now().withNano(0));
}
So every time it runs I have a log that points out when it started and finished, along with a "unique" identifier (Spring uses same instance at #Scheduled classes with no extra configuration, this.toString returned same string everytime). Every execution takes 5 seconds to complete.
I thought that cron expression meant "runs everytime every 37 seconds" but it didn't.
Using * * * * * * I got this:
started -1615036471 at 10:18:46
finished -1615036471 at 10:18:51
started 2090620070 at 10:18:52
finished 2090620070 at 10:18:57
started -349207943 at 10:18:58
finished -349207943 at 10:19:03
Which made sense: it takes 1s to start a new execution after a previous one was finished, always taking 5s to complete. But when I used */37 * * * * * I got
started -644623959 at 10:54
finished -644623959 at 10:54:05
started 212117957 at 10:54:37
finished 212117957 at 10:54:42
started 1788724609 at 10:55
finished 1788724609 at 10:55:05
started 362510867 at 10:55:37
finished 362510867 at 10:55:42
started -25103618 at 10:56
finished -25103618 at 10:56:05
started -820939074 at 10:56:37
finished -820939074 at 10:56:42
Why it's starting only at seconds 00 and 37? I wanted to implement a similar behavior as Spring's #fixedDelay but flexible to be changed at some properties file(#fixedDelay only accept constants).

I don't think that you can actually do this only with cron, for a number such as 37.
The easiest option, would be to select an increment that can divide 60.
Basically an even number that is equal to ( or less than) 30.
E.g. So 10, 15, 20, or 30.
For 10, your expression would be:
cobra.tarifas.intervaloEntreCobrancas =0,10,20,30,40,50 * * * * *
Otherwise, you could just go for once per minute.
0 * * * * *

Related

Spring Scheduler to run at different timings on a single day

I have a requirement where my scheduler has to run for every hour between 9 AM to 12 PM everday and then it runs once by 3PM and 5 PM respectively.
How can i make my CRON expression to work according to the requirement
So far i have tried with below cron expression
#Scheduled(cron="0 0 9-12 * * *")
But that runs for every hour from 9 AM - 12 PM
How can i modify it to make it run once by 3 PM and 5 PM also.
I have tried by combining two cron expressions like below but that dint work.
#Scheduled(cron="0 0 9-12 * * *, 0 0 3 * * *")
Can i give 2 cron expressions through 2 #Scheduled like below
#Scheduled(cron="0 0 9-12 * * *")
#Scheduled(cron="0 0 9-12 * * *")
public void myMethod() {}
Would that be a feasible solution?
Can anybody help me with this?
#Schedules annotation can be used to set multiple calendar-based timer expressions.
This annotation will get rid of the redundancy of writing the same
method multiple times.
In the following example, the first expression sets a timer to expire on the last day of every month. The second expression sets a timer to expire every Friday at 11:00 PM.
#Schedules ({
#Schedule(dayOfMonth="Last"),
#Schedule(dayOfWeek="Fri", hour="23")
})
public void doPeriodicCleanup() { ... }

Problem with cron job which has to run every 15 minutes but not at 15,30,45

So i have a cron job that runs and executes fine (hence why no path is shown) at:
*/15 * * * *
but I don't want that as it means it runs at every fifteen minutes past 0 of the hour according to crontab.guru which gives tasks run at 15,30 and 45 minutes.
This is actually what I want:
1/15 * * * *
which according to crontab.guru should begin the 15 minutes at 1 minute past the hour and run the tasks at 16, 31 and 46 minutes.
Now the problem is when I crontab -e to set up the cron job of 1/15 * * * * I get a bad minute error from crontab, yet as i say in my opening lines using */15 * * * * returns no error from crontab and the task is executed. Why is this?.
You could do 1,16,31,46 * * * * to run the jobs at 1, 16, 31 and 46 minutes every hour.

How to set two cron on the same springboot method?

I want to set a timer at 9:00 / 16:30. But one cron can not realize it.
So i need two cron to realize it. The corn is as follows:
cron1: * 30 16 * * *
cron2: * * 9 * * *
I want to set cron by springboot #Schedule like this
#Scheduled(cron = "0 0 2 * * ?")
public void sayHello(){}
But it seems that can not support two #Scheduled label on one method or two cron in one label.
The so low method is as follow, Any better advice?
#Scheduled(cron = "* 30 16 * * ?")
public void sayHello(){}
#Scheduled(cron = "* * 9 * * ?")
public void subSayHello(){sayHello();}
I think it is difficult because of the different min and different hour,
if the cron run in the same hour or min, it will be easy.
Such as:
"* 0,30 9 * * ?"
"* 0 9,16 * * ?"
Or you can see this link Cron expression to run job twice a day at different time?

#Scheduled for every one hour doesn't work. tried various options

i need to use #Schedule spring annotation to with cron parameter to run the job for every one hour. I have tried various option but it doesn't seems to work.
Could someone help me with the valid expression to run for every 1 hour?
ex: 1:00 2:00 3:00 4:00 5:00 6:00 7:00 etc.,
Referred: http://www.baeldung.com/spring-scheduled-tasks and http://www.baeldung.com/cron-expressions
Tried the following
0 0/60 * * * *
0 * 0/1 * * *
* * 0/1 * * *
* * 0/60 * * *
Thanks.
FixedRate annotation got worked to run for every hour
#Scheduled(fixedRate=60*60*1000)
public void scheduleFixedRateTask() {
System.out.println(
"Fixed rate task - " + System.currentTimeMillis() / 1000);
}
FixedRate annotation to run for every hour with 10 minutes delay. Incase if you want to make an initial delay to start the job, you can specify "initialDelay". If you specify this value, the the very first time job will be started after the given delay. In the below example, the method is scheduled to run at every hour with initial start delay as 10 minutes.
#Scheduled(fixedRate=60*60*1000, initialDelay=10*60*1000)
#Component
public class SomeScheduler {
#Scheduled(cron = "0 0 0/1 * * ?")
public void print() {
System.out.println("====>> print method()...");
}
}
#EnableScheduling
#Configuration
public class AppStarter {
}
Spring #Scheduled annotation has a optional element called timeUnit to setup the time unit use in the fixedDelay, fixedDelayString, fixedRate, fixedRateString, initialDelay, and initialDelayString
So to run a job every one hour #Scheduled(fixedRate = 1, timeUnit = TimeUnit.HOURS)
For other time units (TimeUnit Enum constants) see the docs
#Scheduled(fixedRate = 1, timeUnit = TimeUnit.HOURS)

Job execution in a jee environment

I am working on an application that gives its users the ability to do financial transactions. I have some operations that need some days to be executed.
So I want to know if there is a way to execute these operations in the expected day without my intervention, I mean it should be automatically done by the system.
I am actually working with spring framework and I have done some researches and find out the Task Execution and Scheduling supported by spring framework. but I don't know if this is a good choice for my case because I don't know if this job executer will work even if my application is not running and as you know the transactions execution should be done with or without running the application.
I am new to spring framework and especially to this job thing.
can anyone please explain to me this 'Job' concept and how to use it in my case.
Scheduling Tasks with spring is very reliable, however your application must be running.
You can use cron expressions to set the trigger, in this example it will run every day from Monday to Friday at 2a.m.
#Component
public class ScheduledTasks {
private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
#Scheduled(cron="0 0 2 * * MON-FRI")
public void reportCurrentTime() {
log.info("The time is now {}", dateFormat.format(new Date()));
}
}
here how to build cron expressions spring like
Example patterns:
"0 0 * * * *" = the top of every hour of every day.
"*/10 * * * * *" = every ten seconds.
"0 0 8-10 * * *" = 8, 9 and 10 o'clock of every day.
"0 0 6,19 * * *" = 6:00 AM and 7:00 PM every day.
"0 0/30 8-10 * * *" = 8:00, 8:30, 9:00, 9:30, 10:00 and 10:30 every day.
"0 0 9-17 * * MON-FRI" = on the hour nine-to-five weekdays
"0 0 0 25 12 ?" = every Christmas Day at midnight

Resources