Quartz Fire Time is off by an hour - c#

I recently upgraded from 1.x to the latest version 2.1.2. I ran the db scripts and made the necessary code changes and we're just testing it now. Everything seems to work as expected with one odd exception. We have a little UI that we query the qrtz_trigger table for so we can see all the schedules when things will run.
When I schedule a Job with a daily CRON trigger it will run at the correct time the first run, but the subsequent time it will be off by one hour. So for example say I schedule a daily job to run at 2:30 PM every day, my cron expression looks like:
0 30 14 ? * MON-SUN
And the CRON expression appears as such in the db as well. When I look in the qrtz_triggers table I see the following (converted from ticks):
NEXT_FIRE_TIME: 2013-08-15 14:30:00.000
PREV_FIRE_TIME: NULL
So far so good. But then the trigger fires, runs the job and the qrtz_triggers table is updated to:
NEXT_FIRE_TIME: 2013-08-16 13:30:00.000
PREV_FIRE_TIME: 2013-08-15 14:30:00.000
We keep all our servers running on UTC to avoid confusion.
Is this a bug? What might be going on here? We don't see this behavior in 1.x

Related

Reschedule already planned jobs. Despite changing the EnqueueAt value, the task is executed according to the initially specified date

I’m in the process of deploying an application that uses Hangfire’s solutions in 1.7.24 version with the MySQL database.
I am struggling with one problem. The application automatically schedules actions and adds these calls as BackgroundJob in hangfire. The problem is that these jobs cannot run on user-defined holidays or weekends. This means that if a job that is to be processed on a weekend or holiday should be moved to the next possible date.
Is it possible to move an already scheduled job, or is the only solution (which I don’t quite like and want to do) to delete the current scheduled job and add a new one with the updated date?
I tried to deserialize the data available in the table “hangfire.hangfirestate” for the corresponding scheduled job, I changed the value of the “Data” column for “EnqueueAt”.
The Hangfire dashboard correctly shows in this case that the job is to be performed on the date and time I changed manually, but unfortunately for some reason the Hangfire server does not take these changes and procced the job execution on this initial date.
Can you help with this topic? Thank you in advance.

How to solve the sleeping problem in Quartz.NET (C #)?

I am having a problem with Quartz.NET to create a job on a system. The Quartz is sleeping 23:50 and waking up 7:26 AM.
I have a job scheduled for 00:00
System Information: 1 - .NET Application 2 - IIS Server
Application log:
enter image description here
I personally just use quartz job calculator the set job execute time when server is up
https://www.freeformatter.com/cron-expression-generator-quartz.html
and have the ability to manually start them later if needed.
You can also create a job that automates this. For example it runs every 10m that checks if some other job has to be run. It does so by checking when it was last ran, and if it is ran it will set a sync lock - a simple local time, so you can check if some amount of time ex: 1 day has passed.

How do I make Quartz Scheduler to run every hour not to run if the previous hour's job is not yet completed?

I did setup a Cron Job that runs every hour in C# as a service; it sweeps files from a folder and dumps them onto ftp, however during busy hours one hour is not enough, how do we make sure that the previous hours job is completed first before starting this hours job.
There's an attribute called [DisallowConcurrentExecution] which you can use. Refer to the documentation pertaining to the exact version of Quartz Scheduler.NET that you are using.
You can find more info about it at https://www.quartz-scheduler.net/documentation/quartz-3.x/tutorial/more-about-jobs.html

How to update the database once when the timer expires?

I am using an ASP.NET web form and I have two fields Start_date and End_date in it.
I want to update a particular field in SQLServer once when the time goes beyond the End_date (i.e. the deadline is expired).
e.g. if the End_date is on 06/09/2015, then the SQLServer field should be updated as Expired at 12.01 AM on 06/10/2015.
I am new to ASP.NET and please let me know if you have any ideas. Thank you
There are way too many ways to do such thing. I.e:
making a SQL script that does that and adding that script as scheduled job in SqlServer
or, creating a WindowsService that sleeps and wakes up every hour or six and checks for expired records
or, adding a module like Hangfire to your ASP application and adding such scheduled task there
..
Those three are probably the most often used.
Anyways, it's always about some scheduler and some job to do periodicaly. Think how to write one "run" of the job (find expired, mark/delete them), then read about what schedulers you can use, then glue it together and configure the scheduler and done.
There are several ways to do this, but if all you need to do is make database changes at a given time, then I recommend using the SQL Server Agent. You can set it up to run just once or on a recurring schedule and you can set it up to run a stored procedure or you can feed it straight SQL commands.

Quartz.Net problems updating a job, error reporting/monitoring

I have a quartz.net client/server setup to fire some text messages on a schedule using another Third Party library.
Quartz.Server.exe is running as a windows service on my staging and development environments, pointing to jobs on SQL and my website uses Quartz.Simpl.ZeroSizeThreadPool and just schedules the jobs. Everything was working fine until it wasn't.
Apparently something had caused the exe to stop running and even though it was running as a windows service with recovery options set to send me an email when it went down, I did not get the email.
So when I restarted the server 15 days worth of old text messages went out with misleading phrases like "Appointment tomorrow # 9:00 AM" for appointments for 5 days ago.
So now I have updated my IJob code so that the job is discarded if the fire-time is after the appointment time. Since I was using DateTime instead of plain strings I changed "quartz.jobStore.useProperties = false". When I was ready to deploy I realized that this change along with some other changes could break the scheduler so that it wouldn't fire historical triggers from before the changes.
I spiraled down a 12+ hour black hole trying to wrestle with the settings to get my new jobs to fire alongside my old jobs locally and on my staging environment. Tried a million things, including every combination of Quartz running as a service or console pointing to SQL local or on staging. Said potty-words. Then said some prayers.
Started over. Tested to see if the working code on the live server would fire both new and old jobs without testing. It wouldn't. I Changed "quartz.jobStore.useProperties = false" in quartz.config. It worked! So I did a new deployment Monday evening with the changes and everything seemed to be working fine. I did a "Keeping my job dance", and revisited my error logging/recovery setup and created a nightly job in SQL to count number of triggers yesterday, today, and tomorrow each morning.
Here it is Wednesday morning and I check the SQL job I set up to find 150+ triggers from Yesterday have not been handled (everything past 9:00 AM EST). So I go to my live server and the Quartz service is still running. I stop the process and go to my folder where it lives and Right_Click>Run as Admin. Here is the error I get in my log.txt file. And of course now the Windows service fails to start.
I need major help fast! I need a montage, and at the end of the Montage I need to be a quartz.net ninja. Marko Lahma (or anyone) will you "hold my hand" and tell me I am going to be able to keep my job? I need my setup to be bulletproof (be more robust/fail more noticeably).
EDIT - 201404241938Z
Here is my code to check for the new values that broke the old jobs
// I think this next line is causing an error
DateTimeOffset oDateReminder = data.GetDateTimeOffset("reminderTime");
if (oDateReminder.DateTime > DateTime.MinValue)
{
// Do stuff with other "new job" datamap keys
…
// Changing it to…
if (data["reminderTime"] != null)
{
// Do stuff with other "new job" datamap keys
…
EDIT - 201404242205Z
This seems to have worked. I'll wait and award some bounty
As you probably know, the data is now corrupted in the DB containing both JobDataMaps (binary) and NameValueCollections (binary).
Would you like to give a whirl to the latest head of repository master? I've ninjacommitted support for recovering from this mixed data situation. Just take the latest and build with custom snk file and drop the DLL for run.
This is version 2.2.x so take note if you are using something like 2.1 or 2.0.
The issue is tracked here https://github.com/quartznet/quartznet/issues/172
What comes to your original issue one easy fix would to ignore misfires, if SMS notification doesn't fire within expected time then it probably should be ignored and not fired immediately when possible. Logging information might help you get info about what caused the original downtime (windows updates, SQL server not started yet etc).

Categories