I've a windows service that creates and hosts some jobs (today the number is 64, it can go up to 1400) to be executed as different schedules. Out of those 64 that I currently have say 30 should kick off at 4 AM and 4 PM every day, 10 should kick off at 3 AM and 3 PM every day and the remaining 14 should kick off at 5 AM and 5 PM everyday. I see that few of the jobs are being triggered properly according to the schedule and it is leaving several jobs behind and never triggering them.
When I looked at the crons expressions in the QRTZ_ tables and the Next fire time all looks good. I've had the following configurations and the below is my code to create and trigger the schedules. What must be going wrong and how can I figure that out.
IJobDetail objJobDet = JobBuilder.Create<AuditProcessor>()
.WithIdentity("Job-" + obj.Key.ToString(), AuditType.ToString())
.UsingJobData(obj.Key)
.Build();
ITrigger objJobTrigger = TriggerBuilder.Create()
.WithIdentity("Trigger-" + obj.Key.ToString(), AuditType.ToString())
.StartAt(new DateTimeOffset(startAtTime))
.WithCronSchedule(objCronExp[obj.Key], x => x.WithMisfireHandlingInstructionIgnoreMisfires())
.Build();
QrtzController.AddJobToScheduler(objJobDet, objJobTrigger);
Config:
<add key="QrtzSchedulerInstanceName" value="SignAuditInstance"/>
<add key="QrtzSchedulerInstanceId" value="SignAuditInstanceOne"/>
<add key="QrtzThreadPoolType" value="Quartz.Simpl.SimpleThreadPool, Quartz"/>
<add key="QrtzthreadCount" value="50"/>
<add key="QrtzThreadPriority" value="Normal"/>
<!--Job Store Properties-->
<add key="QrtZJobStoreMisfireThreshold" value="60000"/>
<add key="QrtzJobStoreType" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"/>
<add key="QrtzJobStoreUseProps" value="false"/>
<add key="QrtzJobStoreDataSource" value="default"/>
<add key="QrtzJobStoreClustered" value="false"/>
Related
I want to make the C# windows service application run only once a year instead of Daily
This has to happen every year on the same date and same time.
For example:
the Date has to be March 31 and the time should be 23:59
I'm trying to do this from App.config file
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<appSettings>
<add key ="Mode" value ="YEARLY"/>
<!-- <add key ="Mode" value ="Interval"/>-->
<add key ="IntervalMinutes" value ="1"/>
<add key ="ScheduledTime" value ="23:59:00"/>
<add key = "ScheduledDate" value =""/>
</appSettings>
</configuration>
I want to make it happen on the above mentioned date and time. How can I get this done? Thanks in advance...
Make a service which has a timer, every x seconds it checks to see if the current time + x seconds is greater than the target time. Once this magical moment has been triggered, do that thing you wanted to do, then the service goes back to 'checking the time' for another 365 days.
Obviously a scheduled task would be a more sensible solution, but sensibility isn't always compatible with out requirements :)
im the new in Quartz.NET (v.3.0.3).I have console application and it's quartz host and broadcasting tcp.x:555/QuartzScheduler.
In my company we have 2 app server machines and they're master-slave themselves.If master app is down slave take it's place.We will setup console application ( as a service ) in these servers.
If we do that what happens in Quartz.NET , is these schedulers will be same or different ?
PS: we're using MsSQL jobStore (AdoNetJobStore).
Thank you for reply.
I found my own solution in this page ;
Quartz.NET Clustering
I duplicate my console app and change port address (1 : localhost:555 port , 2 : localhost:556 port ) , create six jobs three of them run in 30 sec , others run in 60 sec.we run them in same time and here what quartz do ;
running same PC Console App
and my properies ;
<quartz>
<add key="quartz.scheduler.instanceName" value="RemoteServer"></add>
<add key="quartz.scheduler.instanceId" value="AUTO"></add>
<add key="quartz.jobStore.clustered" value="true"></add>
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz"></add>
<add key="quartz.threadPool.threadCount" value="5"></add>
<add key="quartz.threadPool.threadPriority" value="Normal"></add>
<!-- Tcp Hosting-->
<add key="quartz.scheduler.exporter.type" value="Quartz.Simpl.RemotingSchedulerExporter, Quartz"></add>
<add key="quartz.scheduler.exporter.port" value="556"></add>
<add key="quartz.scheduler.exporter.bindName" value="QuartzScheduler"></add>
<add key="quartz.scheduler.exporter.channelType" value="tcp"></add>
<add key="quartz.scheduler.exporter.channelName" value="httpQuartz"></add>
<!-- DB-->
<add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"></add>
<add key="quartz.jobStore.useProperties" value="true"></add>
<add key="quartz.jobStore.dataSource" value="myDS"></add>
<add key="quartz.jobStore.tablePrefix" value="[dbo].QRTZ_"></add>
<add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"></add>
<add key="quartz.dataSource.myDS.connectionString" value="Data Source=xxx;Initial Catalog=xxx;User ID=xxx;Password=xxx"></add>
<add key="quartz.dataSource.myDS.provider" value="SqlServer"></add>
<add key="quartz.serializer.type" value="binary"></add>
Thank you !
I am using an ASP.Net website as a sort of back-end control panel, and I want to set it up so that when the user adds something to my database, it will create/schedule a job to send out a reminder to everybody on some date.
I have the job and trigger parts down and working, however I want to set it up to use AdoJobStore so that these jobs won't be lost (in case there is an instance where the reminder doesn't have to be sent out for a whole month or two).
I've tried using their official tutorial, some relevant posts here, and other guides I've found through google, but I can't figure out how to set this up at all. Most provide code that needs to be added to some kind of configuration file, but I can't seem to find any - I have seen them saying to edit quartz.config, web.config, or quartz.properties. I can only find the web.config in ASP.net my project, but I can't seem to get any of the examples working inside this file.
You need to define an ADOJobStore in your app.config/web.config and then some quartz.config. I call mine QuartzDataStoreSettingsDatabase.config
<configSections>
<section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<quartz configSource="QuartzDataStoreSettingsDatabase.config" />
Then the file for quartz specific stuff
QuartzDataStoreSettingsDatabase.config
<quartz>
<add key="quartz.scheduler.instanceName" value="ExampleDefaultQuartzSchedulerFromConfigFileSqlServer"/>
<add key="quartz.scheduler.instanceId" value="instance_one"/>
<add key="quartz.threadPool.threadCount" value="10"/>
<add key="quartz.threadPool.threadPriority" value="Normal"/>
<!--
org.quartz.scheduler.idleWaitTime
Is the amount of time in milliseconds that the scheduler will wait before re-queries for available triggers when the scheduler is otherwise idle. Normally you should not have to 'tune' this parameter, unless you're using XA transactions, and are having problems with delayed firings of triggers that should fire immediately.
It defaults to every 30 seconds until it finds a trigger. Once it finds any triggers, it gets the time of the next trigger to fire and stops checking until then, unless a trigger changes. -->
<add key="quartz.scheduler.idleWaitTime" value ="5000"/>
<!-- Misfire : see http://nurkiewicz.blogspot.com/2012/04/quartz-scheduler-misfire-instructions.html -->
<add key="quartz.jobStore.misfireThreshold" value="60000"/>
<add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"/>
<add key="quartz.jobStore.tablePrefix" value="QRTZ_"/>
<add key="quartz.jobStore.clustered" value="false"/>
<add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"/>
<add key="quartz.jobStore.dataSource" value="MySqlServerFullVersion"/>
<add key="quartz.jobStore.useProperties" value="false"/>
<add key="quartz.dataSource.MySqlServerFullVersion.connectionString" value="SuperSecret!!"/>
<add key="quartz.dataSource.MySqlServerFullVersion.provider" value="SqlServer-20"/>
</quartz>
See my answer here:
Unable to save anything to the Quartz.net ado store
Then when an "event" happens in your website world.......you need to schedule a job programatically.
NameValueCollection config = (NameValueCollection)ConfigurationManager.GetSection("quartz");
ShowConfiguration(config, logger);
ISchedulerFactory factory = new StdSchedulerFactory(config);
IScheduler sched = factory.GetScheduler();
/* the below code has to be tweaked for YOUR Job */
IJobDetail textFilePoppingJobJobDetail = JobBuilder.Create<TextFilePoppingNonConcurrentJob>()
.WithIdentity("textFilePoppingJobJobDetail001", "groupName007")
.UsingJobData("JobDetailParameter001", "Abcd1234")
.Build();
ITrigger textFilePoppingJobJobDetailTrigger001 = TriggerBuilder.Create()
.WithIdentity("textFilePoppingJobJobDetailTrigger001", "groupName007")
.UsingJobData("TriggerParameter001", "Bcde2345")
.UsingJobData("TempDirectorySubFolderName", "MyTempDirectorySubFolderName")
.UsingJobData("DestinationFullFolderName", #"C:\SomeFolder")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(10)
.RepeatForever()
/* .WithRepeatCount(1) */
)
.Build();
sched.ScheduleJob(textFilePoppingJobJobDetail, textFilePoppingJobJobDetailTrigger001);
I've created an ASP.NET MVC website. Then I've created a class library named Site.Scheduler where I wanted to put all my triggers and jobs.
I've created a simple job for testing purposes
public class CurrencyRatesJob : IJob
{
private readonly IBudgetsRepository budgetsRepository;
public CurrencyRatesJob(IBudgetsRepository budgetsRepository)
{
this.budgetsRepository = budgetsRepository;
}
public void Execute(IJobExecutionContext context)
{
try
{
var budgets = new BudgetsDTO();
var user = new UserDTO();
budgets.Sum = 1;
budgets.Name = "Quartz";
user.Email = "email#g.com";
budgetsRepository.InsertBudget(budgets, user);
}
catch (Exception ex)
{
throw new Quartz.JobExecutionException(ex);
}
}
}
and a Job Scheduler
public class CurrencyRatesJobScheduler
{
public static void GetCurrencyRates()
{
try
{
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
IJobDetail job = JobBuilder.Create<CurrencyRatesJob>().Build();
ITrigger trigger = TriggerBuilder.Create()
.StartNow()
.WithSimpleSchedule
(s =>
s.WithIntervalInSeconds(10)
.RepeatForever()
)
.Build();
scheduler.ScheduleJob(job, trigger);
}
catch (Exception ex)
{
ex.ToString();
}
}
}
To start the scheduler when application starts, I've added the following in Global.asax.cs
CurrencyRatesJobScheduler.GetCurrencyRates();
So after all that, I was expecting the job to execute every 10 seconds and insert all that info in the DB, but it doesn't do anything and I get no errors either.
Does anyone know what could be the issue?
EDIT:
So I've created all the necessary tables (executed the script from Quartz.NET) and I've added a new App.config file in my class library
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="quartz.scheduler.instanceName" value="MyQuartzScheduler" />
<add key="quartz.scheduler.instanceId" value="instance_one" />
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="10" />
<add key="quartz.threadPool.threadPriority" value="1" />
<add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
<add key="quartz.jobStore.misfireThreshold" value="60000" />
<add key="quartz.jobStore.dataSource" value="default" />
<add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz" />
<add key="quartz.jobStore.lockHandler.type" value="Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz" />
<add key="quartz.jobStore.tablePrefix" value="QRTZ_" />
<add key="quartz.dataSource.default.connectionString" value="Server=(local);Database=My.Database;UID=User;PWD=Password" />
<add key="quartz.dataSource.default.provider" value="SqlServer-20" />
<add key="quartz.jobStore.useProperties" value="true" />
</appSettings>
</configuration>
Still no luck. Besides that, no triggers or jobs were stored in the DB.
You need to call
scheduler.Start();
First thing that stands out, you haven't started scheduler. So quartz is not running.
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
scheduler.Start();
After starting it the server will scan the db for job details/triggers and proceed accordingly.
However, you also want to add proper identities to your job detail/trigger. These are needed for quartz to create primary keys, otherwise you will get a SchedulerException.
IJobDetail job = JobBuilder.Create<CurrencyRatesJob>()
.WithIdentity("currencyJob", "group1")
.Build();
ITrigger trigger = TriggerBuilder.Create()
.StartNow()
.WithIdentity("currencyJob", "group1")
.WithSimpleSchedule(s => s.WithIntervalInSeconds(10).RepeatForever())
.Build();
Regarding your config file, you need to declare an appropriate quartz section and add the settings there (by default this is where StdSchedulerFactory looks to create properties)
<configuration>
<configSections>
<section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</configSections>
<quartz>
<add key="quartz.scheduler.instanceName" value="MyQuartzScheduler" />
<add key="quartz.scheduler.instanceId" value="AUTO" />
...
</quartz>
</configuration>
i am also facing the same issue. i fixed the issue by placing config information in the app.config in the consuming application. As Class Library does not capable of running independently. It should be referenced by another app maybe console or web site. we need to place all config items in the consuming application this may be help. cheers. happy sharing
I'm trying to run Quartz.net server for my website maintance tasks.
I create Jobs and triggers in my WCF application (hosted on IIS). So they can be stored in database (SQL Server).
Now i can't understand ADO.NET Job Store.
Here is my web.config part for Quartz.net:
<configSections>
<section name="quartz" type="System.Configuration.NameValueSectionHandler" />
</configSections>
<quartz>
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="10" />
<add key="quartz.threadPool.threadPriority" value="Normal" />
<add key="quartz.jobStore.misfireThreshold" value="60000" />
<add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
<add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.**SqlServerDelegate**, Quartz" />
<add key="quartz.jobStore.tablePrefix" value="QRTZ_" />
<add key="quartz.jobStore.dataSource" value="ConnectionString" />
<add key="quartz.dataSource.ConnectionString.connectionString" value="Server=*;Database=*;Uid=*;Pwd=*" />
<add key="quartz.dataSource.ConnectionString.provider" value="SqlServer-20" />
<add key="quartz.scheduler.instanceName" value="PaymentService" />
<add key="quartz.jobStore.useProperties" value="true" />
</quartz>
And here is my global.asax:
public class Global : System.Web.HttpApplication
{
public static ISchedulerFactory Factory;
public static IScheduler Scheduler;
protected void Application_Start(Object sender, EventArgs e)
{
Factory = new StdSchedulerFactory();
Scheduler = Factory.GetScheduler();
JobKey JobKey = new JobKey("GetOrderInfoJob", "Project");
if (Scheduler.CheckExists(JobKey))
Scheduler.DeleteJob(JobKey);
IJobDetail job = JobBuilder.Create<PaymentServiceLogic>()
.WithIdentity(JobKey)
.StoreDurably()
.RequestRecovery()
.Build();
TriggerKey triggerKey = new TriggerKey("GetOrderInfoTrigger", "Project");
TriggerBuilder tb = TriggerBuilder.Create();
tb.WithIdentity(triggerKey );
tb.WithSimpleSchedule(a => a.WithIntervalInMinutes(1));
tb.StartNow();
tb.ForJob(job);
ITrigger trigger = tb.Build();
Scheduler.ScheduleJob(trigger);
Scheduler.Start();
}
}
Once i've started WCF service on localhost, QRTZ_JOB_DETAILS table in SQL Server for jobs had 1 entry, but no triggers.
I've tested this code a couple times and now no jobs are storing and therefore i have this exception:
Couldn't store trigger job: The job referenced by the trigger does not exist.
Is there some bug with job's building or AdoJobStore?
And the second question is about how to do correct shutdown in global.asax. Now i've decided this method:
protected void Application_End(object sender, EventArgs e)
{
ICollection<IScheduler> all = Factory.AllSchedulers;
foreach (IScheduler item in all)
{
item.Shutdown(true);
}
}
and implementing my own logging in Application_Error.
Note, sure whether it is a good idea to ask two questions in one, but the answer to your first question is you need to change
Scheduler.ScheduleJob(trigger);
to
Scheduler.ScheduleJob(job, trigger);
The former is when the job has previously been added to the scheduler, whereas the latter adds both the job and trigger at the same time.