I am noticing that sometimes quartz scheduler is automatically pausing some of the jobs. Is this a bug or any configuration issue?
All scheduled jobs are using CronTrigger.
I am suspecting that whenever server is stopped, it maybe automatically pausing running job? I have following code for ServletContextListener for shutdown of application.
public void shutdownScheduler(Scheduler scheduler) {
try {
if (null != scheduler) {
scheduler.shutdown();
}
} catch (Exception e) {
log.error(e);
}
}
Some of the quartz properties are listed below...
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 20
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.jobStore.misfireThreshold = 60000
Yes, it does go to standBy mode by default. If you check the code you will see that one of the first thing the code does after calling shutdown is invoking the standby() function.
If you want to avoid this behaviur, you have the option to call shutdown with a parameter:
shutdown(true)
which will force the Scheduler to wait for running jobs to complete first.
Confirmation is in the doc, but not too much about the details unfortunately.
Related
I have a web app which runs an interface for controlling an irrigation system. The system starts up to 10 or so threads, using a ScheduledThreadPoolExecutor.
I have found that when I close down the server, many of these threads continue to run. From the Tomcat catalina.out log:
org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [GH2] appears to have started a thread named [pool-2-thread-1] but has failed to stop it. This is very likely to create a memory leak.
The classes that start these threads are dotted around my app. In order to try to have some control over stopping them, I have a single ScheduledThreadPoolExecutor created by a ServletContextListener and passed into each of the classes that might start a task.
I have tried setting properties in the ScheduledThreadPoolExecutor that I assumed would close down all threads when contextDestroyed() is called in the listener:
public void contextInitialized(ServletContextEvent event) {
executor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(10);
executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
executor.setRemoveOnCancelPolicy(true);
event.getServletContext().setAttribute("executor", executor);
Here is a typical bit of code that schedules a thread:
public WeatherScheduler(ScheduledThreadPoolExecutor executor) {
this.executor = executor;
checkEveryHour();
}
public void checkEveryHour() {
final Runnable weatherChecker = new Runnable() {
public void run() {
if (!Thread.interrupted()) {
if (Date_TimeUtils.isBetween7amAnd8pm()) {
weather = new Weather();
weather.getNewForecast();
IrrigationLogger.getInstance().logEvent("weather forecast: " + weather.toString());
} else
LOGGER.log(Level.INFO, "weatherChecker not called as isBetween7amAnd8pm() == false ");
}
}
};
// delay of a minute to allow for getting internet connection, repeat every hour
executor.scheduleAtFixedRate(weatherChecker, 1, 60, TimeUnit.MINUTES);
}
When the server is closed down, the contextDestroyed() method is called in the listener, and I have
executor.shutdownNow();
included in that method.
But still I get the message in the log file that threads have been started that can't be stopped.
What am I missing?
Thanks.
The way any ThreadExecutor tries to stop a currently running thread is by setting interrupt flag by invoking Thread class method interrupt() on that thread. It is responsibility of the running thread to detect that it was "asked" to finish, so the running thread should clean up and terminate once the signal received. So first in your runner code surround it with try-catch where you will catch InterruptedException and also in your runner code you suppose to invoke method Thread.currentThread().isInterrupted() and if it returns true clean up and finish the thread (same as in your catch statement)
I'm using quartz job my requirement is like I get some data to be persist in DB but before that I need to perform some modification on given data so I started processing the data in background using quartz. But now what is happening some of the time job is getting standby even before starting and due to that some of the data payload didn't get processed.
How can I maintain the job to be wait until the job complete its work.
scheduler.start();
scheduler.scheduleJob(job, trigger);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
scheduler.standby();
In my code if job starts before 3 second the standby will wait for job to complete the task but some of the time job taking more time to stat.
Instead of making your job wait for data, you can
Start your job every x minutes
Don't spawn new jobs if there's already a working one so they
won't overlap
I'd like to develop a Java program that executes tasks registered in a database. The tasks have their own cron-like schedule, which is an object of CronExpression of Quartz Scheduler, and saved in the database after being serialized.
Tasks should be executed anytime according to its schedule, so I think the program should be daemonized, and may be able to be restarted or stopped outside the program (like an usual service beneath /etc/init.d/)
I'm studying the examples of Quartz
and saw the program running continuously even if there's no sleep and shutdown method. This seems nice to achieve my purpose, but I'm not sure if this way can generate a daemon process.
// TODO: Retrieve cron format from the database
Trigger trigger = org.quartz.TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.withSchedule(cronSchedule("* * * ? * MON-FRI"))
.startNow()
.build();
try {
sched.scheduleJob(job, trigger);
sched.start();
// Thread.sleep(90L * 1000L);
// sched.shutdown(true);
} catch (SchedulerException e) {
...
My question is
What is the best way to build a cron job scheduler which runs continuously on a server?
Thank you in advance, and any opinions or questions would be appreciated.
What is the difference between pauseJob() and pauseTrigger() in quartz scheduler?
How can select one among them for use? now i want to pause/interept a specific job how can i do
my scheduler code is given bellow
JobDetail job = new JobDetail();
job.setName("pollerjob"+pollerId);
job.setJobClass(Pollersheduller.class);
job.getJobDataMap().put("socialMediaObj", socialMediaObj);
job.getJobDataMap().put("queue", queue);
//configure the scheduler time
SimpleTrigger trigger = new SimpleTrigger();
trigger.setName("pollerSocial"+pollerId);
trigger.setStartTime(new Date(System.currentTimeMillis() + 1000));
trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
trigger.setRepeatInterval(Long.parseLong(intervel));
//schedule it
Scheduler scheduler = null;
try {
scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
As you have probably noticed, in Quartz a single job can be associated with multiple triggers. And if you look into Quartz sources, you will see that the pauseJob method simply retrieves all triggers associated with the specified job and pauses them, whereas the pauseTrigger method pauses only a particular trigger. So that is the main difference.
Please note that pausing a job in Quartz does not pause a currently running running job, it merely prevents the job from being run in the future!
If you want to interrupt a running job, then you can use the interruptJob method defined in the org.quartz.Interruptable interface the job must implement. If your job implements this interface, then it is entirely up to you to implement the interrupting logic. For example, you can set some sort of a flag when the interruptJob method is called and then you need to check the value of this flag in the job's execute method.
I am using Guava's SimpleTimeLimiter to get Timeout functionality. The problem is that shutting down the app (if it's finished) take 30s as soon as i use the SimpleTimeLimiter (this time does not change if i change timeout). If i call new MyCallable().call() directly all works fine - app is shut down as soon as last task is finished.
The app itself has an own shutdown hook to be able to handle ctrl-c (to finish last task). The app uses a H2- embedded db and Network.
I tried to profile with visualvm - the time at the end is not recorded?! This long waiting period tooks placed before my shutdown hook is called (probably another shutdown hook?).
Any ideas how to fix this?
When you create SimpleTimeLimiter with default constructor - he create own Executors.newCachedThreadPool() that you can't control, So your application what until all threads will be completed. from Javadoc
... Threads that have not been used for sixty seconds are
terminated and removed from the cache....
If you create own ExecutorService and create SimpleTimeLimiter with this executorService then you can shutdown executorService on your shutdown hook.
private final ExecutorService executor;
private final TimeLimiter timeLimiter;
...
executor = Executors.newCachedThreadPool();
timeLimiter = new SimpleTimeLimiter(executor);
...
public void shutdown() {
if (executor == null || executor.isShutdown()) {
return;
}
executor.shutdown();
try {
executor.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
log.log(Level.WARNING, "Interrupted during executor termination.", e);
Thread.currentThread().interrupt();
}
executor.shutdownNow();
}