where should I locatemy Quartz Code in asp.net - quartz-scheduler

I have an asp.net website and want to do a task once a day.
the task is: sending email to users 2 days before expiration of their registration.
I used Quartz.NET version 1.0. I have wrote a sample code that opens a window in each second. Now I don't know where should I locate this code in my asp.net project?! it is now in a simple page. I want it to be independent from pages.
public class DumbJob : IJob
{
public DumbJob()
{
}
public void Execute(JobExecutionContext context)
{
Console.WriteLine("DumbJob is executing.");
System.Windows.Forms.MessageBox.Show("NICE");
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// construct a scheduler factory
ISchedulerFactory schedFact = new StdSchedulerFactory();
// get a scheduler
IScheduler sched = schedFact.GetScheduler();
sched.Start();
// construct job info
JobDetail jobDetail = new JobDetail("myJob", null, typeof(DumbJob));
// fire every hour
Trigger trigger = TriggerUtils.MakeSecondlyTrigger();//.MakeHourlyTrigger();
// start on the next even hour
trigger.StartTimeUtc = TriggerUtils.GetEvenSecondDate(DateTime.UtcNow);
trigger.Name = "myTrigger";
sched.ScheduleJob(jobDetail, trigger);
}
}

There are various ways you can do that...but certainly it's probably better o build some sort of console applications for your case.
Frankly the simplest of which could be a windows schedule task that would trigger every day and launch an exe program (that you'd write using console dotnet) that would check soon-to-expire users and send an email when found...
If you don't want to have user + email code in various places (and centralize all this in your dotnet web app), then I'd create a SOAP/REST end point in your .NET webapp that would be called by a thin client, which would be scheduled by that "windows schedule task"
Quartz would give you more flexibility when it comes to scheduling and doing more enterprise things like job clustering / job high availability / job monitoring for example...
But that'd still be a .NET console app which would start a quartz scheduler, create a trigger, and run forever...(possibly wrapped into a windows "wrapper" service for more control)

Related

How to detect failure of task execution from a vscode extension?

My Visual Studio code extension allows users to deploy and debug applications on remote devices.
To do this I need to have the application "installed" in a local folder that will then be synchronized to the target using rsync.
Some languages/tools provide a simple and standardized way to do this (ex: dotnet publish, for .NET core apps), others don't.
To be flexible and let users choose the method they prefer, my extension relies on a task with a specific name to perform the operation.
I have a resolveDebugConfiguration function that executes the task and then fills out the information inside debug connection to let user debug his app.
As long as this is a single task, this is not an issue. I can start it using vscode.tasks.executeTask and wait for its completion using OnEndTaskProcess. The task should be shell/process and a non-zero exit code means failure. I also check OnEndTask, to be sure that I don't miss other kinds of completition (ex: an invalid path in the cmd field or the user defined a custom task etc.).
Some users may want to have a more complex structure for this. For example having their deployment tasks depend on a build task, to ensure that the latest version is deployed, or perform additional operations in between, so I no longer have a single task, but a chain of tasks connected via dependson.
This is ok and still works...until it fails.
Or, better, until one of the dependency tasks fail.
In this case, I have no notification from OnEndTaskProcess or even OnEndTask and the tasks after the failed one remain inside vscode.tasks.taskExecutions list forever, it seems.
So my resolveDebugConfiguration function never returns and vscode remains in the "starting debugger" state forever...
My code looks like this:
// retrieve task given its name
const tasks = await vscode.tasks.fetchTasks();
var deploy: vscode.Task | undefined = undefined;
for (var task of tasks) {
switch (task.name) {
case "deploy":
deploy = task;
break;
}
}
if (deploy === undefined) {
// error message telling user that he has to define a task named "deploy"
return null;
}
var emitter = new EventEmitter();
// the process event arrives before the generic terminate one (checked inside vscode sources)
vscode.tasks.onDidEndTaskProcess(e => {
if (e.execution.task.name === "deploy") {
emitter.emit("terminated", e.exitCode);
}
});
vscode.tasks.onDidEndTask(e => {
// check if task is still running, otherwise report an error
var taskexecutions = vscode.tasks.taskExecutions;
for (var taskexecution of taskexecutions) {
if (taskexecution.task.name === "deploy") {
return;
}
}
emitter.emit("terminated", -1);
});
try {
var execution = await vscode.tasks.executeTask(deploy);
}
catch (e) {
// catch execution exceptions and show a message to the user
return null;
}
var code = await new Promise<Number>((resolve, reject) => {
emitter.on("terminated", code => resolve(code));
});
if (code !== 0) {
// deploy task failed
return null;
}
// local deployment succeeded, move on...
Some of the tasks may take a long time, so using a timeout may be a solution worse than the problem.
It would be nice to have OnEndTask called even when a dependency fails, preventing the actual task from running, but this does not seem to happen.
I plan to open an issue on vscode github repo, but maybe someone has a solution that doesn't involves changes to the ide itself.

Quartz: Show list of completed task

I don't know if this is the best place to ask, but is it possible to query Quartz completed jobs ?
I can't find a solution, I already visited quartz website and googled it.
If you are looking for information on historical run like start, end time (duration), params with which it was invoked you need to create your own table to persist those information.
The way i have done this in the past is
Created a new JOB_LOG table
Created a Custom Quartz Job Listener by extending JobListenerSupport http://www.quartz-scheduler.org/api/2.1.7/org/quartz/listeners/JobListenerSupport.html
Depending on your requirement add your persistence logic to
#Override
public void jobToBeExecuted(JobExecutionContext context) {
//insert here
}
#Override
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
//insert here
}

Quartz Scheduler Job Auto Termination

How do I create a Quartz Scheduler job that terminates automatically after given amount of time (if running job takes too much time)?
A Quartz scheduler has no built-in functionality to interrupt a job by itself after a given amount of time.
If you dont want to interrupt Jobs (see the interface InterruptableJob) manually (for example with rmi), you could easily establish such a automatically termination.
Either:
When starting a scheduler, fork a deamon-thread that runs periodically and checks whether some of the currently running jobs must be interrupted. For Example you could use a JobDataMap to store the maximum execution time on a per job instance basis.
Each Job could control its maximum execution time in a similar way.
To stop a job from the inside of the job itself the easiest way is to throw an exception after a specific amount of time. For example:
public class MyJob : IJob
{
Timer _t;
public MyJob()
{
TimeSpan maxRunningTime = TimeSpan.FromMinutes(1);
_t = new Timer(delegate { throw new JobExecutionException("took to long"); }, null, (int) maxRunningTime.TotalMilliseconds,
-1);
}
public void Execute(IJobExecutionContext context)
{
// do your word
// destroy T before leaving
_t = null;
}
}
Hope it helps :)

Display progress when running long operation?

in my ASP.NET MVC3 Project, I've got an action which runs a certain amount of time.
It would be nice, if it could send partial responses back to the view.
The goal would be to show the user some progress-information.
Has anybody a clue how to make that work?
I did a try with some direct output to the response, but it's not being sent to the client in parts but all on one block:
[HttpPost]
public string DoTimeConsumingThings(int someId)
{
for (int i = 0; i < 10; i++)
{
this.Response.Write(i.ToString());
this.Response.Flush();
Thread.Sleep(500); // Simulate time-consuming action
}
return "Done";
}
In the view:
#Ajax.ActionLink("TestLink", "Create", new AjaxOptions()
{ HttpMethod = "POST", UpdateTargetId="ProgressTarget" })<br />
<div id="ProgressTarget"></div>
Can anybody help me making progressive action-results?
Thanks!!
Here's how you could implement this: start by defining some class which will hold the state of the long running operation -> you will need properties such as the id, progress, result, ... Then you will need two controller actions: one which will start the task and another one which will return the progress. The Start action will spawn a new thread to execute the long running operation and return immediately. Once a task is started you could store the state of this operation into some common storage such as the Application given the task id.
The second controller action would be passed the task id and it will query the Application to fetch the progress of the given task. During that time the background thread will execute and every time it progresses it will update the progress of the task in the Application.
The last part is the client: you could poll the progress controller action at regular intervals using AJAX and update the progress.

Help and advice needed working with Quartz.NET NthIncludedDayTrigger

I've started using Quartz.NET recently, and so far, it's been really
helpful. Now, I'm trying to use it to create a job that runs once a
month using a NthIncludedDayTrigger (I want to use the
NthIncludedDayTrigger as eventually I will be specifying a calendar to
exclude weekends/holidays).
To familiarise myself with the code, I've
set up a simple console application to create an NthIncludedDayTrigger
where the first fire time will be 15 seconds from now:
static void Main(string[] args)
{
IScheduler scheduler = StdSchedulerFactory.DefaultScheduler;
scheduler.Start();
var jobDetail = new JobDetail("Job name", "Group name", typeof(SomeIJobImplementation));
var trigger = new NthIncludedDayTrigger();
trigger.Name = "Trigger name";
trigger.MisfireInstruction = MisfireInstruction.NthIncludedDayTrigger.DoNothing;
trigger.IntervalType = NthIncludedDayTrigger.IntervalTypeMonthly;
//I'm using the following while experimenting with the code (AddHour(1) to account for BST):
trigger.FireAtTime = DateTime.UtcNow.AddHours(1).AddSeconds(15).ToString("HH:mm:ss");
//I'm using the following while experimenting with the code:
trigger.N = DateTime.Today.Day;
Console.WriteLine("Started, press any key to stop ...");
Console.ReadKey();
scheduler.Shutdown(false);
}
...
public class SomeIJobImplementation : IJob
{
public void Execute(JobExecutionContext context)
{
Logger.Write(String.Format(
"Job executed called at {0}",
DateTime.Now.ToString("dd-MMM-yyyy HH:mm:ss")), null, 1,
TraceEventType.Information);
}
}
Running this results in the job being executed multiple times
(approximately once per second) for one minute. I'm using an ADO.NET
job store and can see in my database that QRTZ_TRIGGERS.NEXT_FIRE_TIME
is set to the last executed time, i.e. doesn't seem to be scheduled to
run again.
I expected the above code to run the job once (after about 15
seconds), then schedule the job to run again in one months time.
Perphaps the issue is just with the way I'm using Quartz.NET whilst
I've been experimenting or, maybe, my expectations are wrong? Either
way, I would be most grateful for any help/suggestions to explain the
behaviour I've observed, and what I need to change to get the
behaviour I want.
I must be late but I was trying to implement the same solution and ended up here.
I reckon you should star the scheduler after you've defined jobs and triggers.