How does quartz track the time - java

How does quartz track the time ? Is it a continuous timer running in background or does it somehow uses the OS scheduler or is it something else ?
Which class actually holds this feature ?
Thanks.

As far as I digged into Quartz source code, I found (at least for StdScheduler implementation which is proxy of QuartzScheduler) that its scheduling thread QuartzSchedulingThread uses System.currentTimeMillis() for prediction of the next job trigger run.
Please look inside QuartzSchedulerThread.java .

Related

Spring's #Scheduled(fixedDelay=...) stops at midnight

I have a Spring Boot application that uses a #Scheduled annotation with a fixed delay. The annotation is used in different classes with different delays. However, at midnight every day all scheduled tasks stop running.
Does anyone know why this might be happening? I can't find any explanation online.
(I am using version 2.0.2.RELEASE of Spring Boot and 5.0.6.RELEASE of Spring Core.)
Thanks in advance!
I'm not sure what do you mean about stopping running.
But the first work you need to do is starting your schedules on different threads and put them into a queue.
If stopping means suspending for a while,then you create a new schedule that make other schedules sleep some time at midnight.Maybe the new schedule should have be started when the thread are sleeping,and the way to prevent is to make sure only one schedule(I mean same kind of schedule) could be put in the queue at the same time.
If you just mean kill all other schedule at midnight,you just need to start your midnight schedules and kill others.
So sorry about my poor English,hope this could help you.
#Scheduled(fixedDelay = 1000)
void scheduleFixedDelayTask() {
System.out.println(
"Fixed delay task - " + System.currentTimeMillis() /
1000);
}
In this case, the duration between the end of last execution and the start of next execution is fixed. The task always waits until the previous one is finished.
This option should be used when it’s mandatory that the previous execution is completed before running again.
So maintain the delay such a way that the previous execution completed.
Hope it helps.
Thanks to everyone who replied.
As it turns out, this was not an issue with Spring. It appeared the tasks stopped because the logs stopped. What really happened was that our scripts that tail the logs were not smart enough to handle log files that roll at midnight (face palm).

Is Spring's built in Scheduler persistent.?

I have run into a case where I have to use a persistent Scheduler, since I have a web application that can crash or close due to some problems and might lose it job details if this happens . I have tried the following:
Use Quartz scheduler:
I used RAMJobStore first, but since it isn't persistent, it wasn't of much help. Can't setup JDBCJobStore because, this will require huge code changes to my existing code base.
In light of such a scenario,
I have the following queries:
If I use Spring's built in #Schedule annotation will my jobs be persistent..? I don't mind if the jobs get scheduled after the application starts. All I want is the jobs to not lose their details and triggers.?
If not, are there any other alternatives that can be followed , keeping in mind that I need to schedule multiple jobs with my scheduler.?
If yes, how can I achieve this.? My triggers are different each job. For e.g I might have a job that is scheduled at 9AM and another at 8.30AM and so on.
If not a scheduler, then can I have a mechanism to handle this.?
One thing, I found is that the documentation for Quartz isn't very descriptive. I mean it's fine for a top level config, but configuring it on your an application is a pain. This is just a side note. Nothing to do with the question.
Appreciate the help. :)
No, Spring's #Schedule-annotation will typically only instruct Spring at what times a certain task should be scheduled to run within the current VM. As far as I know there is not a context for the execution either. The schedule is static.
I had a similar requirement and created db-scheduler (https://github.com/kagkarlsson/db-scheduler), a simple, persistent and cluster-friendly scheduler. It stores the next execution-time in the database, and triggers execution once it is reached.
A very simple example for a RecurringTask without context could look like this:
final RecurringTask myDailyTask = ComposableTask.recurringTask("my-daily-task", Schedules.daily(LocalTime.of(8, 0)),
() -> System.out.println("Executed!"));
final Scheduler scheduler = Scheduler
.create(dataSource)
.startTasks(myDailyTask)
.threads(5)
.build();
scheduler.start();
It will execute the task named my-daily-task at 08:00 every day. It will be scheduled in the database when the scheduler is first started, unless it already exists in the database.
If you want to schedule an ad-hoc task some time in the future with context, you can use the OneTimeTask:
final OneTimeTask oneTimeTask = ComposableTask.onetimeTask("my-onetime-task",
(taskInstance, context) -> System.out.println("One-time task with identifier "+taskInstance.getId()+" executed!"));
scheduler.scheduleForExecution(LocalDateTime.now().plusDays(1), oneTimeTask.instance("1001"));
See the example above. Any number of tasks can be scheduled, as long as task-name and instanceIdentifier is unique.
#Schedule has nothing to do with the actual executor. The default java executors aren't persistent (maybe there are some app-server specific ones that are), if you want persistence you have to use Quartz for job execution.

java.util.Timer stops without any exception

I go to the FTP each 2 mins to upload new files.
I implemented it with java.util.Timer. But after some time - several days or even week - it stops without any exception and without any reason.
I found thread:
Java unlimited thread stops after some time
But there is no particular solution in it.
I read about ScheduledExecutorService, but as far as I understand - it's the same as Timer.
Please give me some ideas!
You can try to set a default Exception handler using Thread.setDefaultUncaughtExceptionHandler() API in your main thread and try to log any throwable/exception that could get swallowed silently.
I just saw that no one have answered this question, maybe because this is a duplicate.
ScheduledExecutorService uses System.nanotime() and Java.util.Timer uses System.currentTimeMillis().
System.currentTimeMillis() depends up on system time and System.nanotime() gives nanoseconds since some fixed arbitrary initial time and is not related to system time. So any change in system time (due to NTP time correction or system stand-by) may or may not impact Timer execution. This would be the reason that your timer fails.
For more details please refer - What should Timertask.scheduleAtFixedRate do if the clock changes?

How to simulate 'No. of occurrences' or 'Repeat Count' with CronTriggers in Java?

I am using the Quartz Scheduler (version 1.8.3 due to project constraints) and I as assigned the task of creating an "MS Outlook-like" scheduler for Jobs specific to my project. Everything seems fine to work fine but I have a really huge problem with CronTriggers (this problem also exists in version 2.1 of Quartz):
I am using CronTriggers for recurrence patterns of DAILY, WEEKLY and MONTHLY. In addition to the recurrence pattern, I also provide an option for 'No. of occurrences'. This has become the bane of my life! CronTrigger does not provide an option for 'repeatCount' like SimpleTriggers do (bug: https://jira.terracotta.org/jira/browse/QTZ-242?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel). Apparently this may be fixed in version 2.2 but I cannot wait that long nor do I believe my problem is unique!
A few options that I deemed worthy of investigation:
Calculate the 'EndTime' for the CronTrigger but using my own logic - this fails to cover all possible cases and is only approximate at best even for simple cases.
Use a TriggerListener or JobListener to keep track of no. of iterations of the job since I just need the job to stop after 'N' iterations and I have a 1:1 mapping from Job instance to Trigger. This does not seem very feasible and/or efficient by any stretch of the imagination.
Could any of you who have used CronTriggers with the option of 'No. of occurrences' please give some insights on how to solve this conundrum?
It seems that Quartz have implemented something that can help: TriggerUtils.computeEndTimeToAllowParticularNumberOfFirings.
I haven't tested it yet, but this is the code I have wrote for now:
CronTrigger trigger = newTrigger()
.withSchedule(cronSchedule(cronExpression))
.build();
Date endDate = TriggerUtils.computeEndTimeToAllowParticularNumberOfFirings((OperableTrigger) trigger,
new BaseCalendar(Calendar.getInstance().getTimeZone()), 10);
trigger = trigger.getTriggerBuilder().endAt(endDate).build();
If this won't work, then as said here and here, you can't set a repeat count, and you should use TriggerListener.
In any case, version 2.2 doesn't have this feature.
Update
I've tested it, and it works.
Wy dont't you instead use the Simple Trigger? You would have the additional taks of calculating the time interval at the time of scheduling the job, but that will be a one time activity.

How can I load file into web app through certain periods?

I have next task: I need to load the same file into my web app several times, for example - twice a day! Suppose in that file I have information, that changes, and I need to load this info into my app to change the statistics for example.
How can I load file several times (twice an hour, or twice a day)?
What should I use? Is any algorithm to do that?
I am not allowed to use external libraries like Quartz Scheduler. So I need to do it with Thread and/or Timer. Can anybody give me some example or algorithm how to do it. Where can I create the entry point to my Thread, can I do it in managed bean or I need some sort of filter/listener/servlet. I works with jsf and richFaces. Maybe in this technologies there are some algorithms to solve my problem.
Any ideas?
Thanks very much for help!
If you cannot use a scheduler, then use a servlet and Timer.
In this article it is described how to do that. It's exactly what you need.
Check java.util.Timer, it should be just enough for what you need
how about this:
http://www.quartz-scheduler.org/overview/index.html
I'd use the Quartz Scheduler. I don't know the architecture of your app so I can't really say if Spring configuration or just code configuration is better. You could use a SimpleTrigger, or even a CronTrigger if you want a more expressive scheduling.
I would expose entry point to 'load' functionality as a servlet in your webapp and then use external scheduler (cron on Unix, Scheduled Tasks on Windows) to call that servlet via wget or any other command line http client.
This approach has advantages of not depending on any third party libraries (adding Qurtz just for one task seems like overkill for me) and also has flexibilty of changing schedule without touching your code as well as triggering 'load' manually if desired.
Thanks all for help - I do this task with help of Timer, TimerTask and ServletContextListener:
servletContext = event.getServletContext();
// create the timer and timer task objects
Timer timer = new Timer();
// get a calendar to initialize the start time
Date startTime = Calendar.getInstance().getTime();
List<Company> companies = CompanyUtils.getInstance().getCompanies();
if (companies.size() == 0)
return;
for (int i = 0; i < companies.size(); i++)
{
FileUpdater task = new FileUpdater(companies.get(i).getUrl());
// schedule the task to run hourly
timer.scheduleAtFixedRate(task, startTime, companies.get(i).getUpdatePeriod());
}
// save our timer for later use
servletContext.setAttribute("timer", timer);
Once more thanks!
With best wishes!

Categories

Resources