Quartz job getting triggered at wrong times - quartz-scheduler

Issue Description:
We are having a quartz job which is scheduled to run at different times during the day say 1PM and 4PM and 7PM. Issue is that the job is getting triggered and executed on times other than the scheduled times also.
What we did:
We have already tried shutting down our servers completely (JBoss) and clearing quartz tables but that hasn't worked at all.
We are using quartz 1.6 and I want to know, if there is any bug in the version and if quartz upgrade can resolve the issue OR
If there is any problem with setting up quartz properties and if properties can be tweaked to resolve this.
Edit - more details below:
I have corrected the job timings now. Also, job is getting triggered at any random times other than these we mentioned in its schedule. There is no pattern in when it is getting triggered apart from the scheduled times.
Below are the job and trigger details in DB properties file. Based on these job details and trigger details will be set up in DB in Quartz_Triggers and Quartz_CronTrigger tables:
<job>
<job-detail>
<name>Match Job</name>
<group>JB_QUARTZ</group>
<job-class>com.qd.qehadmin.common.scheduler.MatchJob</job-class>
<volatility>false</volatility>
<durability>true</durability>
<recover>true</recover>
</job-detail>
<trigger>
<cron>
<name>Match Job Trigger</name>
<group>JB_QUARTZ</group>
<job-name>match Job</job-name>
<job-group>JB_QUARTZ</job-group>
<cron-expression>0 0 13,16,19 * * ?</cron-expression>
</cron>
</trigger>
</job>
Below are the quartz properties details in DB:
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName = JB_QUARTZ
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = true
org.quartz.jobStore.dataSource = jobSchedulerDS
org.quartz.jobStore.tablePrefix = JB_QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 10000
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.jobSchedulerDS.jndiURL=java:JBAPI
org.quartz.dataSource.jobSchedulerDS.java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
#java.naming.provider.url=jnp://localhost:3099
java.naming.provider.url=jnp://166.20.337.12:8441,166.20.337.14:8441,166.20.337.16:8441,166.20.337.19:8441
#============================================================================
Below is the Java code for job:
public void execute(JobExecutionContext ctx) throws JobExecutionException
{
try{
//Scheduler scheduler = new StdSchedulerFactory().getScheduler();
SendEmail sm = new SendEmail();
boolean running = false;
if (ctx.getJobDetail().getKey().getName().equalsIgnoreCase("match Job") ) {
LogFile.MATCH_JOB.logInfo("Match jobs size : "+ctx.getScheduler().getCurrentlyExecutingJobs().size(), this.getClass().getName());
if(ctx.getScheduler().getCurrentlyExecutingJobs().size()==1)
{
initClient(); //This method will read properties from DB
startTime=System.currentTimeMillis();
Match(); //This method will execute job level code
endTime=System.currentTimeMillis();
LogFile.MATCH_JOB.logInfo("***Match job ends*** Loadtest: "+Constants.loadTest+" in time: "+(endTime-startTime)/1000 + "secs", this.getClass().getName());
}
else
{
running=true;
}
}
if(running)
{
LogFile.MATCH_JOB.logInfo("The Match job is already running – sending email",this.getClass().getName());
sm.sendEmail();
}
}catch(Exception e){
e.printStackTrace();
LogFile.MATCH_JOB.logError("***Match Job Error*** " +e.getStackTrace(), this.getClass().getName());
}
}

Related

How to publish a basic message to RabbitMQ exchange using op-rabbit

I've been trying to get a very simple app working to publish messages to a RabbitMQ exchange using the Scala op-rabbit library to no avail.
I'm clearly doing something wrong, but the docs are very limited regarding message publishing.
I can get the actor to connect to RabbitMQ. However, upon publishing a message, it doesn't appear in Rabbit.
Here is the code I'm using to publish the message:
object RmqPublisher extends App {
val actorSystem = ActorSystem("my-actor")
private lazy val config: Config = ConfigFactory.load()
val rabbitControl: ActorRef =
actorSystem.actorOf(Props {
new RabbitControl(
ConnectionParams.fromConfig(config.getConfig("op-rabbit.rabbit"))
)
}
)
rabbitControl ! Message.exchange("Test", "amq.direct", "my_routing_key")
}
Here is my config:
op-rabbit {
topic-exchange-name = amq.direct
channel-dispatcher = "op-rabbit.default-channel-dispatcher"
default-channel-dispatcher {
# Dispatcher is the name of the event-based dispatcher
type = Dispatcher
# What kind of ExecutionService to use
executor = "fork-join-executor"
# Configuration for the fork join pool
fork-join-executor {
# Min number of threads to cap factor-based parallelism number to
parallelism-min = 2
# Parallelism (threads) ... ceil(available processors * factor)
parallelism-factor = 2.0
# Max number of threads to cap factor-based parallelism number to
parallelism-max = 4
}
# Throughput defines the maximum number of messages to be
# processed per actor before the thread jumps to the next actor.
# Set to 1 for as fair as possible.
throughput = 100
}
rabbit {
exchange-name ="amq.direct"
routing-keys = "my_routing_key"
virtual-host = "/"
hosts = ["localhost"]
username = "guest"
password = "guest"
port = 5672
ssl = false
connection-timeout = "5s"
max-tps = 1000
}
}
The logs suggest it is connected successfully as can be seen below:
[INFO] [08/04/2020 21:49:39.219] [my-actor-op-rabbit.default-channel-dispatcher-5] [akka://my-actor/user/$a/connection/$a] akka://my-actor/user/$a/connection/$a connected
[INFO] [08/04/2020 21:49:39.223] [my-actor-akka.actor.default-dispatcher-4] [akka://my-actor/user/$a/connection] akka://my-actor/user/$a/connection connected to amqp://guest#{localhost:5672}:5672//
[INFO] [08/04/2020 21:49:39.230] [my-actor-akka.actor.default-dispatcher-2] [akka://my-actor/user/$a/connection/confirmed-publisher-channel] akka://my-actor/user/$a/connection/confirmed-publisher-channel connected
Any ideas what I'm doing wrong?

Quartz schedulers controlled from an external app

I am currently working on Quartz.NET (version 2.3.1). I have created different Schedulers with different jobs using the code below (for each scheduler):
NameValueCollection properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "QuartzSchedulerTest";
properties["quartz.scheduler.instanceId"] = AUTO;
properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
properties["quartz.threadPool.threadPriority"] = "Normal";
properties["quartz.jobStore.misfireThreshold"] = "60000";
properties["quartz.jobStore.clustered"] = "true";
properties["quartz.jobStore.tablePrefix"] = "QRTZ_";
properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz";
properties["quartz.jobStore.dataSource"] = "default";
properties["quartz.jobStore.useProperties"] = "false";
properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz";
properties["quartz.dataSource.default.connectionString"] = "myConnString"
properties["quartz.dataSource.default.provider"] = "SqlServer-20";
// Get scheduler
ISchedulerFactory sf = new StdSchedulerFactory(properties);
IScheduler scheduler = sf.GetScheduler();
Now I have all scheduling information stored on a SQL database and everything works.
I created a new Console Application because I need to manage all schedulers (get schedulers list, jobs for each scheduler, send command to pause and resume triggers ecc...).
This is the code I wrote to try to have handlers to all existing schedulers:
NameValueCollection properties = new NameValueCollection();
properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
properties["quartz.threadPool.threadPriority"] = "Normal";
properties["quartz.jobStore.misfireThreshold"] = "60000";
properties["quartz.jobStore.clustered"] = "true";
properties["quartz.jobStore.tablePrefix"] = "QRTZ_";
properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz";
properties["quartz.jobStore.dataSource"] = "default";
properties["quartz.jobStore.useProperties"] = "false";
properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz";
properties["quartz.dataSource.default.connectionString"] = "myConnString"
properties["quartz.dataSource.default.provider"] = "SqlServer-20";
// Get scheduler
ISchedulerFactory sf = new StdSchedulerFactory(properties);
var schedulers = sf.AllSchedulers;
But no handlers returned (schedulers count is 0). Can anyone tell me how can I get all schedulers? Is it possible?
Sorry for my english and thanks in advance.
You have to connect to each scheduler instance directly using remoting. The schedulers are not aware of each other and there is no way to get a list of all of the schedulers that are in a cluster.
Once you connect to each scheduler then you'll be able to pull a list of running jobs and manipulate the job schedule as necessary. If all of the schedulers are in a cluster, then you don't have to connect to all of them to manipulate the jobs themselves. You can do that from any of the instances. However, the list of running jobs has to be compiled by asking each scheduler individually.

Sugar scheduler job won't run

Hi I've got a scheduler in my custom/Extension/modules/Schedulers/Ext/ScheduledTasks folder with a file name that's the same as my function name (fetch_account_pricing_info_from_recurly)
/* make the scheduler visable in the job creator */
array_push($job_strings, 'fetch_account_pricing_info_from_recurly');
function fetch_account_pricing_info_from_recurly(){
$GLOBALS['log']->fatal('my fatal message');
/* select all the active accounts */
$sql = "SELECT * FROM accounts INNER JOIN accounts_cstm ON accounts_cstm.id_c = accounts.id WHERE status_c = 'Active Customer'";
$result = $GLOBALS['db']->query($sql);
while($row = $GLOBALS['db']->fetchByAssoc($result)){
/* iterate over the accounts fetching the recurly subscription info from the SugarRecurlySyncService */
$account = BeanFactory::getBean('Accounts', $row['id']);
try{
$account->recurly_amount_c = 100;
$account->recurly_valid_c = true;
$account->save();
}catch(Exception $e){
}
}
return true;
}
I've done a quick build and repair so that its contents show up in modules/Schedulers/ext/ScheduledTasks/scheduledtasks.ext.php
I've created a job based on this scheduler that is supposed to run every minute from the admin interface, but when I run the cron jobs from the command line
php -f cron.php
I see this line related to my job
Wed Sep 11 16:41:12 2013 [11966][1][DEBUG] process_full_list: Scheduler(641c28bd-44ad-0b02-f7ad-522e4e2abb93): name = Update Pricing
Wed Sep 11 16:41:12 2013 [11966][1][DEBUG] process_full_list: Scheduler(641c28bd-44ad-0b02-f7ad-522e4e2abb93): job = function::fetch_account_pricing_info_from_recurly
If the job were actually running though I'd think that the fatal log would show up in the log file. So why isn't it running?
When I checked my job_queue table I saw that i had an entry with a status of 'running' instead of 'done'. Deleting that row fixed my problem

spring with quartz.properties

I am trying to store the quartz scheduled job in the database by using postgreSQL.
The database name is "testdb" and the schema is "testschema". I have the following quartz.properties. I have a following quartz.properties, but I am getting this error message "org.postgresql.util.PSQLException: ERROR: relation "quartz_triggers" does not exist".
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = quartz_
org.quartz.dataSource.myDS.driver = org.postgresql.Driver
org.quartz.dataSource.myDS.URL = jdbc:postgresql://localhost:5432/postgres
org.quartz.dataSource.myDS.user = postgres
org.quartz.dataSource.myDS.password = welcome123
org.quartz.dataSource.myDS.maxConnections 10
Could anyone tell me what is wrong?
First of all, you must run the installation script that creates the quartz tables in your database.
The files are available in the full quartz jar file (/docs/dbTables)
Here is the documentation: http://quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-09
M.

Quartz JDBCJobstore doesn't work

I have downloaded Quartz and I am trying to run a sample.
I have a sample that uses JDBCJobStore which doesn't work but this sample works fine with RAMJobStore.
Just when I choose JDBCJobStore and exception get raised.
I am using quartz-1.6.5.
code:
package test;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
public class ReportRunner {
public static void main(String[] args) {
try {
SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
Scheduler sched = schedFact.getScheduler();
sched.start();
JobDetail jobDetail = null;
SimpleTrigger trigger2 = null;
jobDetail = new JobDetail("Income Report", "Report Generation",
QuartzReport.class);
jobDetail.getJobDataMap().put("type", "FULL");
jobDetail.setDurability(true);
trigger2 = new SimpleTrigger("Income Report", "Report Generation");
trigger2.setStartTime(new java.util.Date(
System.currentTimeMillis() + 4000));
trigger2.setRepeatInterval(5000);
trigger2.setRepeatCount(100);
sched.scheduleJob(jobDetail, trigger2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package test;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class QuartzReport implements Job {
public void execute(JobExecutionContext cntxt) throws JobExecutionException {
System.out.println("Generating report - "
+ cntxt.getJobDetail().getJobDataMap().get("type"));
}
}
config file:
org.quartz.scheduler.instanceName = Sched1
org.quartz.scheduler.instanceId = 1
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = myDS
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://192.168.0.4:3306/conference
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password =root
org.quartz.dataSource.myDS.maxConnections 5
this the excpetion showd in runtime , it was logged
org.quartz.JobPersistenceException: Couldn't acquire next trigger: Field 'PRIORITY' doesn't have a default value [See nested exception: java.sql.SQLException: Field 'PRIORITY' doesn't have a default value]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTrigger(JobStoreSupport.java:1778)
at org.quartz.impl.jdbcjobstore.JobStoreTX.acquireNextTrigger(JobStoreTX.java:1218)
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:233)
* Nested Exception (Underlying Cause) ---------------
java.sql.SQLException: Field 'PRIORITY' doesn't have a default value
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1056)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3376)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3308)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1837)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1961)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2543)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1737)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2022)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1940)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1925)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:102)
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.insertFiredTrigger(StdJDBCDelegate.java:3360)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTrigger(JobStoreSupport.java:1771)
at org.quartz.impl.jdbcjobstore.JobStoreTX.acquireNextTrigger(JobStoreTX.java:1218)
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:233)
547 [QuartzScheduler_MyClusteredScheduler-NON_CLUSTERED_MisfireHandler] DEBUG org.quartz.impl.jdbcjobstore.SimpleSemaphore - Lock 'TRIGGER_ACCESS' retuned by: QuartzScheduler_MyClusteredScheduler-NON_CLUSTERED_MisfireHandler
java.sql.SQLException: Field
'PRIORITY' doesn't have a default
value
I guess you can tell where the problem lies by seeing the exception above.
I tried with Quartz 1.6.5 and I did't found any result, but it with with Quartz 1.5., I guess there might be some bug in 1.6.5 for JDBC jobstore.
Mohammad
I had a similar problem, and it was my bad.. because I was using version 2.1.1 and I created tables from docs of 2.2.1, I updated the version in Maven and it is working fine now.