I need to start spring scheduling based on the constraint that my scheduler job will run every 5 seconds after a receive a jms message from other component.
What can be the possible way to implement /handle this scenario ,googled for the same but the solutions ask me to have a property in properties file for enabling scheduling which again is static approach.
Kindly suggest some solutions.
You can use:-
Thread.sleep(long delay) after receiving a message from JMS queue i.e. Thread.sleep(300000);
Basically your problem is not related to a scheduler. The message received from the queue is a trigger to invoke the job in your case.
Whereas the scheduled tasks are the ones which keeps repeating them periodically either based on fixed delay or fixed interval or at specific time.
Your job is event based and not on time based so its not a scheduled
job.
Related
DO you know if it's possible to setup some timer event/task to wait for some time for receiving some action? For example, I need to set up some mechanism where I invoke timer task which waits for example for 10 seconds then I will restart checking process.
Thanks,
You can try <pick> It implements the deferred choice workflow pattern, i.e. it can wait for several messages and several timers concurrently. The event that occurs first wins and the contained activity will be executed.
So there is a exists for BPMN which we've used for our needs.
What is exact difference in functionality of JobListener, SchedulerListener and TriggerListener.
Actually I am going to log the start and stop event of all the scheduler in my project so I am thinking about listener.
According to Quartz tutorials :
TriggerListeners and JobListeners
Listeners are objects that you create to perform actions based on
events occurring within the scheduler. As you can probably guess,
TriggerListeners receive events related to triggers, and JobListeners
receive events related to jobs.
Trigger-related events include: trigger firings, trigger mis-firings
(discussed in the “Triggers” section of this document), and trigger
completions (the jobs fired off by the trigger is finished).
SchedulerListeners
SchedulerListeners are much like TriggerListeners and JobListeners,
except they receive notification of events within the Scheduler itself
- not necessarily events related to a specific trigger or job.
Scheduler-related events include: the addition of a job/trigger, the
removal of a job/trigger, a serious error within the scheduler,
notification of the scheduler being shutdown, and others.
I'm a bit new to camel, so please forgive me if this is a stupid question!
In Camel, I have a list of competing consumers against a queue, queue-1. I'd like each consumer to wait 1 hour between attempts to read the queue, but once an hour has passed, each consumer should continuously poll until it receives a message. Once it receives a message, it should process it, and then wait an hour before attempting another read, and so on.
Here's the route I have set up:
from("aws-sqs://queue-1?accessKey=ABC&secretKey=XYZ&maxMessagesPerPoll=1")
.unmarshal().base64()
.unmarshal().serialization()
.throttle(1)
.timePeriodMillis(TimeUnit.HOUR.toMillis(1))
.bean(new ProcessorBean())
.marshal().serialization()
.marshal().base64()
.to("aws-sqs://queue-2?accessKey=ABC&secretKey=XYZ");
It is my understanding that routes execute synchronously (with the exception of specific components designed to work asynchronously). Based on that understanding, I believe this route satisfies those requirements.
Will this do what I want? Why or why not?
Your route will consumes a message in the queue and then wait for one hour.
If you want to wait an hour and then read a message, look at ScheduledPollConsumer Options (Doc)
Some options allow to use scheduler like Quartz2 or Spring based scheduler.
Use the log component if you want to be sure: .to("log:com.mycompany.order?level=DEBUG").
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.
I have an application using the Quartz Scheduler to schedule jobs. The application is currently running Quartz version 1.6.2. My JobStore is org.quartz.impl.jdbcjobstore.JobStoreTX with an Oracle database backing it. Clustering is turned on, but there's only one scheduler using the database. My Quartz threadPool is configured as follows:
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 5
My jobs are long running, so it's fairly common to have 5 jobs running (the maximum allowed by my thead pool) when triggers fire new jobs. The newly triggered jobs misfire and I see log messages like the following:
2011-05-20 04:09:30,097 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:08:29 05/20/2011
2011-05-20 04:09:30,120 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:09:30 05/20/2011
2011-05-20 04:09:30,125 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:08:30 05/20/2011
2011-05-20 04:09:30,138 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:09:30 05/20/2011
2011-05-20 04:11:29,998 INFO [QuartzScheduler_scheduler-servername-111305822376676_MisfireHandler] o.q.impl.jdbcjobstore.JobStoreTX - Handling 2 trigger(s) that missed their scheduled fire-time.
Once a running job finishes, one of the misfired jobs will get picked up and run normally. However, Quartz seems to pick up a misfired job randomly, with no regard to the order the jobs had been originally scheduled to execute. Ideally, I'd like them to be picked up in the order they were supposed to have run, based on their original fire times.
Is it possible to make my waiting (misfired) jobs get fired in the order they were triggered once space in the Quartz ThreadPool becomes available?
When quartz handles a trigger that has missed it's fire time it will update the nextFireTime of the trigger. By default a trigger will be considered missed if it's nextFireTime is over 60 seconds in the past. Missed triggers should still be selected based on nextFireTime and priority order but I'm guessing it seems random because some triggers have been updated and others haven't.
I would suggest increasing the org.quartz.jobStore.misfireThreshold property. See http://www.quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigRAMJobStore.html (although the property is identical for all JobStores). This should make it less likely for your triggers to be re-scheduled.
I sounds like you are running into a misfiring scenario (a scenario where there are more jobs ready to be executing than there are worker threads). Set the misfire instruction and/or priority property on the triggers to change how each behaves after it has past its fire time.
Also, you could consider increasing the misfire threshold, which would change the amount of time that a trigger can be "late" waiting for a thread to execute on before it is considered misfire (and has its misfire instruction applied to it).
Is it possible to make my waiting (misfired) jobs get fired in the order they were triggered once space in the Quartz ThreadPool becomes available?
The "do nothing" instructions will leave the fire times as-is.
Looking at the quartz thread pool , it uses a wait()/notify() loop, which is not fair, and will randomly select a new thread when multiple threads are waiting.
You could use your own instance of ThreadPool which is fair. Copy the code from SimpleThreadPool, but replace the locking around nextRunnableLock with a java.util.ReentrantLock, passing true to the fair constructor. In your modified SimpleThreadPool, use ReentrantLock.lock()/unlock() instead of synchronized, and use ReentrantLock.newCondition().signal()/await() instead of wait/notify, and it might solve your problem.
In case of a CronTrigger, the method updateAfterMisfire() may re-schedule the task at new Date() case MISFIRE_INSTRUCTION_FIRE_ONCE_NOW policy.
If several task are misfired, several of them may be rescheduled at the same time (same millisecond), because computer runs fast.
As a consequence, and if no priority defined, the scheduler will pick-up the first next task, all with same NextFireTime, according to key or full name.
updateAfterMisfire() method should have re-schedule the task to a unique date using a Thread.sleep(25), as an example.