Why Quarz.net job firing multipule time for same trigger instance c# - c#

I am trying to build triggers for a job in Quarz.net based on config settings something like
var keysArray = [1,2]
keysArray.ForEach(key =>
{
//schedule will be unique for a key
var schedule = AppConfig.Get($"CronJobs.{key}.TimeSheetAutoSubmit.Schedule.QuarzExpression") ?? "0 30 23 * * ?";
var timeZoneId = AppConfig.Get($"CronJobs.{key}.TimeSheetAutoSubmit.TimeZoneId") ?? "India Standard Time";
var trigger = TriggerBuilder.Create()
.ForJob(jobDetail)
.WithCronSchedule(schedule, x => x
.InTimeZone(TimeZoneInfo.FindSystemTimeZoneById(timeZoneId)))
.WithIdentity($"TimeSheetAutoSubmitTrigger_{key}")
.WithDescription($"ConfigKey_{key}")
.StartNow()
.Build();
Scheduler.ScheduleJob(jobDetail, trigger);
});
Works fine but problem is trigger is firing multiple times when i check the logs
2017-03-16 12:04:12,247 [DefaultQuartzScheduler_Worker-1] INFO UnitedLex.Services.JobHandlers.timesheetautosubmit - job started
2017-03-16 12:04:13,510 [DefaultQuartzScheduler_Worker-2] INFO UnitedLex.Services.JobHandlers.timesheetautosubmit - job started
2017-03-16 12:04:13,710 [DefaultQuartzScheduler_Worker-2] INFO UnitedLex.Services.JobHandlers.timesheetautosubmit - job started
Don't know what i am doing wrong here....

I may be wrong but I think it's normal because your job builder/scheduler is inside a foreach, the amount of times it gets fired is equal to the length of your array.

If you want your jobs to not run in concurrent mode use this attribute [DisallowConcurrentExecution] on your job definition.
This way the next job trigger will wait for the current running job to finish.

Related

Run Quartz job at specified time

I have a job in Quartz Scheduler which deletes rows from database and I want it to run everyday at 00:00. Currently it has intervalInMinutes set to 1440 (24hrs) but it's wrong. How to set this to run everyday at 00:00?
Code snippet:
x.AddTrigger(x => x,
.ForJob(delete)
.StartNow()
.WithSimpleSchedule(s => s
.WithIntervalInMinutes(1440)
.RepeatForever()
);
There is a simple configuration for a specific recurring job trigger which is like below :
ITrigger t = TriggerBuilder.Create()
.WithIdentity("myTrigger")
.ForJob("myJob")
.WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(0,0)) // execute job daily at 00:00
.Build();
I currently do not have access to an IDE so I can't check it out, but I have found this on the Quartz documentation, maybe this helps you in the right direction.
trigger = TriggerBuilder.Create()
.WithIdentity("trigger8") // because group is not specified, "trigger8" will be in the default group
.StartAt(DateBuilder.EvenHourDate(null)) // get the next even-hour (minutes and seconds zero ("00:00"))
.WithSimpleSchedule(x => x
.WithIntervalInHours(2)
.RepeatForever())
// note that in this example, 'forJob(..)' is not called
// - which is valid if the trigger is passed to the scheduler along with the job
.Build();
Notice how they specify StartAt, maybe you can use that builder to start at 00:00 exactly.
Then with the WithSimpleSchedule set an interval for every 24 hours and repeat forever.
Good luck!
https://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/simpletriggers.html
You can use cron job expressions and here is a helpful link https://www.freeformatter.com/cron-expression-generator-quartz.html
private static readonly string ScheduleCronExpression = "0 * 0 ? * * *";
var trigger2 = TriggerBuilder.Create().WithIdentity("myTrigger", "group1").WithCronSchedule(ScheduleCronExpression).Build();

How can I create a one time pipeline run with a long delay in c# data factory

I need to trigger a pipeline I have built inside of my azure data factory with certain parameters based off of a file I have stored in a database. My problem is that I need to schedule this pipeline to trigger ONCE after a certain amount of time( will usually be hours). This is needed for scheduling and I can't do it event driven. I am using the .NET SDK
I have already created a connection to my data factory and created a schedule trigger. My problem is that a schedule trigger doesn't allow me to trigger one time and then stopping. It requires intervals and a stop date, I tried to set the stop date the same as the start date but it gives me the error of "interval cannot exceed end date".
for (int x = 0; x < intervals.Count; x++)
{
// Create a schedule trigger
string triggerName = location + deliveryDate+x;
ScheduleTrigger myTrigger = new ScheduleTrigger()
{
Pipelines = new List<TriggerPipelineReference>()
{
// Associate the Adfv2QuickStartPipeline pipeline with the trigger
new TriggerPipelineReference()
{
PipelineReference = new PipelineReference(pipelineName),
Parameters = pipelineParameters,
}
},
Recurrence = new ScheduleTriggerRecurrence()
{
StartTime = intervals[x],
TimeZone = "UTC",
EndTime = intervals[x],
Frequency = RecurrenceFrequency.Day
}
};
// Now, create the trigger by invoking the CreateOrUpdate method
triggerResources.Add(triggerName,new TriggerResource()
{
Properties = myTrigger
});
}
I cannot do a pipeline run because there is not way for me to do a run after a certain delay (like 2 hours) if this was possible I would just create a delayed pipeline run...I have tried everything like leaving the frequency blank, changing it to every possibility, and even using different trigger classes like tumbling and event.
There is a simple, crude solution. Create a new pipeline with a parameter of integer type. The first activity in the pipeline will be a Wait Activity. Use the parameter to set how long the Wait Activity should last. The Second activity in the pipeline will be an Execute Pipeline Activity, which depends on the Wait Activity, and will trigger the pipeline you really want to run.
This solution lets you choose how long to wait, then execute the real pipeline you want to run. The Wait Activity is in seconds, I think, so you will need to do some arithmetic. However since you can trigger manually, it shouldn't be a problem.

How can you tell if Hangfire task was manually triggered

I have a Hangfire server set up with several recurring tasks. For local development I don't want these tasks to go through but I need to be able to manually trigger them manually through the Hangfire UI.
I am able to pull the Job Data for the currently running job but I don't see anything within it that tells me if it was manually triggered or not.
Here is an excerpt from my code where RunProcessReportsJob is my RecurringJob in Hangfire
public ExitCodeType RunProcessReportsJob(PerformContext context)
{
var jobId = context.BackgroundJob.Id;
var connection = JobStorage.Current.GetConnection();
var jobData = connection.GetJobData(jobId);
_logger.LogInformation("Reoccurring job disabled.");
return ExitCodeType.NoError;
}
The jobData has a ton of information about the job and context but again I don't see anything within this that tells me if it is a manually triggered job or a scheduled job.
Hope this helps
private bool JobWasManuallyExecuted(string jobId)
{
//'Triggered using recurring job manager' -- Manually triggerd via UI
//'Triggered by recurring job scheduler' -- using scheduller
var jobDetails = JobStorage.Current.GetMonitoringApi().JobDetails(jobId);
if (jobDetails == null)
return false;
return jobDetails.History.ToList().Any(x => x.Reason == "Triggered using recurring job manager");
}
This message appears on the UI as well.
Executed using the scheduler:
Manually executed

How to create recurring Hangfire job every 10 minutes for only 24 hours

When I have a new customer signup that does not complete the process, I send them an email with next steps. I need to create a job that runs every 10 minutes for the first 24 hours after signup. After that time, there is another process that takes over. I schedule the job like this:
RecurringJob.AddOrUpdate(customerId, () => new NewCustomerProcess().checkNewCustomerStatus(customerId)), "*/10 * * * *");
If I add a job start time to the job class:
private DateTime _jobstart = DateTime.UtcNow;
Can I inspect that within the job to figure out when 24 hours has passed then remove the job?
RecurringJob.RemoveIfExists(customerId);
Does Hangfire re-instantiate the job class every time it runs?
if i understand your question correctly.
Hangfire does create a new instance of the job class every time.
So if I needed to solve this problem, I would pass in DateTime as a parameter every time the job is created:
RecurringJob.AddOrUpdate(customerId, () => new
NewCustomerProcess().checkNewCustomerStatus(customerId, DateTime.Now.AddDays(2))), "*/10 * * * *");
And then in the checkNewCustomerStatus compare with DateTime.Now
if (DateTime.Now > dateEnqueued)
{
//Job is complete
return;
}

Quartz.net firing previously scheduled jobs

I just started using Quartz.net. I wrote a little routine to schedule multiple jobs. I am really not sure if I coded this properly. Hopefully there are some Quartz.NET experts that can help. I have three questions:
Does my trigger setup look correct? I would like to run a job everyday at 9AM and 3PM (I know you can't see the market.LocalOpenTime property but its always today's date at 9AM and the other object has 3PM.
I noticed when I run the program, it will always run the 9AM job (scheduled in the past). Anyway I can turn off this feature? I ran the program at 1PM. I assume if I run it at 4PM it will run these two past scheduled jobs.
How can I go about only running these jobs on weekdays?
foreach (IJob job in GetJobsToSchedule())
{
i++;
var market = (IMarket)job;
IJobDetail jobDetail = new JobDetailImpl(market.JobName, null, market.GetType());
ITrigger trigger = new SimpleTriggerImpl(market.JobName, i.ToString(), market.LocalOpenTime, null, 1000, new TimeSpan(1, 0, 0, 0));
sched.ScheduleJob(jobDetail, trigger);
}
1) You might want to consider using a CronTriggerImpl with a schedule of 0 0 9,15 * * ?. This will allow you to set your whole schedule with 1 trigger. Here is a good tutorial on cron triggers (even though it's for the previous Quartz version):
http://quartznet.sourceforge.net/tutorial/lesson_6.html
2) Set the myCronTrigger.MisfireInstruction property to DoNothing. The documentation says this value should be defined in the CronTriggerImpl class but I didn't see it. You may have better luck using IntelliSense in Visual Studio.
3) Check out the Cron tutorial link in (1) above. You could use something like this: 0 0 9,15 * * MON-FRI

Categories

Resources