Quartz.net Jobs after IIS Reset or server shutdown - asp.net

I have used Quartz.Net to schedule some jobs in my ASP.net Application.
I am using default JobStore I think it is RAMJobStore but I am not sure exactly I only know I didn't config anything about Store.
Well the problem is that I want to store all jobs in DB so that I can run remaining jobs again when server resets or shutdown and start again .
I know I can store Jobs to DB using AdoJobStore but I want to know If my application server restarts and application not running in IIS how those remaining jobs can be triggered again ?
Is there any tutorial about this ? does anyone had some experience about triggering stored jobs after server reset ? any help would be appreciated

A. You will use AdoJobStore (as mentioned in comments).
B. You need to understand and tweak the "misfire" configuration. There is not a simple "yes" or "no" answer to this question.
http://royontechnology.blogspot.com/2009/03/so-you-think-you-understand.html
Since quartz.net is a java port over, you can also find helpful information here
http://www.nurkiewicz.com/2012/04/quartz-scheduler-misfire-instructions.html
Here is a sample paragraph (in case that link dies in the future at some point)
Sometimes Quartz is not capable of running your job at the time when
you desired. There are three reasons for that:
(1) all worker threads were
busy running other jobs (probably with higher priority)
(2) the scheduler
itself was down
(3) the job was scheduled with start time in the past
(probably a coding error)
The second one "(2)" (in the above quote) is your scenario.
The then goes on to explain scenarios and options.
Things to internet-search if any of the articles disappear in the future.
java'ish
org.quartz.jobStore.misfireThreshold
c#
"So you think you understand misfireThreshold"

Related

Win 10 Task Scheduler keeps disabling tasks

I use Task Scheduler to run a .bat file that zips and encrypts files and does a nightly backup of them to an external drive. I have used this for years and it has worked just fine. Starting a couple of months ago, the task is getting disabled in Task Scheduler and I cannot figure out why. I can enable it, and it will run again, but then gets disabled again the same day or in the next day or two. Then I noticed that it is not just this task, but other scheduled tasks (that I did not write) that are also getting disabled, all at the same time. Things like Google software update are getting disabled too.
I have been looking at the task history to see when tasks are disabled, and there is no common denominator that I can think of.
When I restart, all tasks are enabled. But what causes them to be disabled?????
I had this for months before I narrowed it down; with the help of posts from the likes of Paul above. Every task kept getting disabled, sometimes several times a day. In my case it was AVG anti-virus.
In AVG settings there is a tools menu, in there is a series of check boxes called "Do Not Disturb Mode". It seems AVG is trying to 'help' the user by not disturbing him if he is running a program full screen by turning off notifications, but it's over zealous and turns off all tasks too.
I unchecked all those tick boxes and didn't have the problem for two months. Then as a test I turned them on again and the tasks got disabled in just an hour or so.
I have had several AVG updates over the period and it's still present, so I don't think it's a bug as much as a feature.
I had the same problem that started in the last few weeks.
If you are running Avast anti-virus, there is bug [feature] that disables scheduled tasks and apparently never re-enables them. See this link: https://forum.avast.com/index.php?topic=249063.0
I had this problem last year. I believe if my memory serves me right that it happens when the Win 10 clock doesn't synchronise and the W32time service has stopped for some reason. If you go into task manager and select services, look for W32time and see if it is running. If it isn't right click and restart it
I had this problem last year. I believe if my memory serves me right that it happens when the Win 10 clock doesn't synchronise and the W32time service has stopped for some reason. If you go into task manager and select services, look for W32time and see if it is running. If it isn't right click and restart it
"Maintains date and time synchronization on all clients and servers in the network. If this service is stopped, date and time synchronization will be unavailable. If this service is disabled, any services that explicitly depend on it will fail to start."
Also check on Windows services for Windows Time to see if it is in manual or Automatic and change it to auto start (W32time)
Wow, thanks for this post. Would never have found out why my scheduled tasks are being disabled. I thought i was being hacked ! Ironically it is Avast's "Do not disturb feature". I had an app to auto-restart, and when this app restarted at the same clock time, all of my scheduled tasks would be disabled. Avast automatically decides to set multiple apps to "Do not disturb = True".
More details: https://forum.avast.com/index.php?topic=249063.0

In web/cloud applications, how can I have an automated task (based on date/time)?

My web site stores invoices.
I would like to process them every night at midnight.
I would also like to send out notices nightly at midnight.
But the web is stateless.
I do not have my own server.
Is there a way?
No, you need a Windows Service on a dedicated box, however the box can be virtual and in the cloud.
You do not own your own server, but your website must be hosted somewhere. You may want to see if you can install windows services on to that server. If you can, I would strongly recommend using a service to run any automated tasks. It is generally frowned upon to use IIS to run automated tasks simply because the process shuts down after periods of inactivity... and if IIS isn't running, neither will your automated task.
A similar question was asked a while back and I think the answers are still very relevant to your problem: Best way to run scheduled tasks
And even further, after google searching I found even more info which you might find helpful:
https://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/
http://www.codeproject.com/KB/aspnet/ASPNETService.aspx
If you absolutely cannot install a service, you could try something like creating a new thread on Application_Start() that checks the time and decides whether or not to run. Then, to keep IIS running during periods of inactivity, you could possibly try spawning a process or something every few minutes to send a request to your server and thus keep it from shutting down.

Running a script just from the server using asp.net

I have a site that I'm working on. Say I need something to run every... say... 30 minutes, how would I get just a simple thing to run like that?
EDIT
I'll be hosting this online with another company. This is why I am not making it as a separate scheduled program.
If you need a process to be run at pre-defined intervals you might be better off using the windows task scheduler, or to create a windows service with a timer. ASP.NET applications aren't ideal for doing this sort of thing, since they are vulnerable to restarts and so you can't guarantee that the process will run at the given interval.
Windows scheduled tasks and services are ideal for this but if you want to run database queries at specified times then I would suggest using SQL Server Agent if you have access to this.
I don't know of any way to reliably do this using ASP.NET. My understanding is: after a certain period of inactivity, IIS will unload your website/webspp from memory. If that happens, your periodic job very likely won't execute, regardless of what technique you used to configure it.
You could, of course, set up some kind of automated system on your own, which occasionally pings your site to keep it from being unloaded. But if you're doing that anyway, well you could just set it up to do the desired operation at the desired interval. :)

Is there a way to run a process every day in a .Net web application without writing a windows service or SQL server jobs

We require that in a ASP.Net application, a .Net process should be invoked every day at a specified time automatically. This process needs to interact with the database (SQL Server 2005) and generate billing on a daily basis. We are using a shared hosting hence we are not able to create a windows service or create SQL Server jobs. How can this be achieved without user intervention?
You could try the technique described here, used at StackOverflow itself (or at least it was used here at one point). In a nutshell:
At startup, add an item to the HttpRuntime.Cache with a fixed
expiration.
When cache item expires, do your work, such as WebRequest or what have
you.
Re-add the item to the cache with a fixed expiration.
To get it to run at a specific time instead of an interval, you could lower the interval and simply modify your working method to check the time itself.
As the comments in the original article linked above note, this isn't a perfect solution, and no one should prefer it over a proper scheduling technique if one is available. See When Does Asp.Net Remove Expired Cache Items? for some additional qualifications.
Yes, use Windows Scheduler. Depending on how it's configured you might need to be logged in for the scheduler to run.
You could always schedule a task to run a webservice..
http://weblogs.asp.net/jgalloway/archive/2005/10/24/428303.aspx
The scheduler would run a VBS file with the following..
Set oServerXML = CreateObject("Msxml2.ServerXMLHTTP")
oServerXML.Open "GET","http://my.hostedservice.com/myService.asmx/myService?aParam=Value
oServerXML.setRequestHeader "Content-Type","application/x-www-form-urlencoded"
oServerXML.Send
Set oServerXML = nothing
Can't be done, unfortunately.
IIS only responds to requests, and SQL Server only wakes up for jobs.
The closest you'll be able to do is to put your routine in an ASPX page, not linked from the site and not with an obvious name, and trigger it by a request from some other machine out on the Internet.
The other machine could be a Windows, Linux, Mac, whatever you have available, and all of those platforms have ways of scheduling events (service, cron, etc.) that can make the request to trigger the update on the server.
There are ways to run "services" in .Net by using cache expiration to trigger the task.
More at CodeProject
You can use a Scheduled Task, but this might not work in a shared hosting environment either.
You could setup a webservice or page on your website to kickoff the process, then have a scheduled task on a desktop machine hit that page/service once daily to start the process. Hacky, but it might work.
Being .NET ignorant, I would imagine there's some kind of .NET based scheduler framework available for this (much like Quartz for Java).
Or you could simply fire off a long running thread that spends the bulk of its time sleeping, wake up every minute, check the time, check it's list of "things to do", fire off the ones that need to be done. Level of sophistication being as far as you want to take it, but the primary goal of keeping the primary scheduling thread "alive", "at all costs".
What i can think about now are:
Create a dll which contain the
schedule logic you want, and make
sure that this dll schedule function
will not stop and will loop for ever,
then you will need a page on that
server this page will fire this dll
functions. "you will need to call
this page at least once to start the
scheduler".
Create an application "holds schedule logic" on another machine, may be your Home PC, and make your pc application call the functions on the server through webservices or pages

Long-running ASP.NET tasks

I know there's a bunch of APIs out there that do this, but I also know that the hosting environment (being ASP.NET) puts restrictions on what you can reliably do in a separate thread.
I could be completely wrong, so please correct me if I am, this is however what I think I know.
A request typically timeouts after 120 seconds (this is configurable) but eventually the ASP.NET runtime will kill a request that's taking too long to complete.
The hosting environment, typically IIS, employs process recycling and can at any point decide to recycle your app. When this happens all threads are aborted and the app restarts. I'm however not sure how aggressive it is, it would be kind of stupid to assume that it would abort a normal ongoing HTTP request but I would expect it to abort a thread because it doesn't know anything about the unit of work of a thread.
If you had to create a programming model that easily and reliably and theoretically put a long running task, that would have to run for days, how would you accomplish this from within an ASP.NET application?
The following are my thoughts on the issue:
I've been thinking a long the line of hosting a WCF service in a win32 service. And talk to the service through WCF. This is however not very practical, because the only reason I would choose to do so, is to send tasks (units of work) from several different web apps. I'd then eventually ask the service for status updates and act accordingly. My biggest concern with this is that it would NOT be a particular great experience if I had to deploy every task to the service for it to be able to execute some instructions. There's also this issue of input, how would I feed this service with data if I had a large data set and needed to chew through it?
What I typically do right now is this
SELECT TOP 10 *
FROM WorkItem WITH (ROWLOCK, UPDLOCK, READPAST)
WHERE WorkCompleted IS NULL
It allows me to use a SQL Server database as a work queue and periodically poll the database with this query for work. If the work item completed with success, I mark it as done and proceed until there's nothing more to do. What I don't like is that I could theoretically be interrupted at any point and if I'm in-between success and marking it as done, I could end up processing the same work item twice. I might be a bit paranoid and this might be all fine but as I understand it there's no guarantee that that won't happen...
I know there's been similar questions on SO before but non really answers with a definitive answer. This is a really common thing, yet the ASP.NET hosting environment is ill equipped to handle long-running work.
Please share your thoughts.
Have a look at NServiceBus
NServiceBus is an open source
communications framework for .NET with
build in support for publish/subscribe
and long-running processes.
It is a technology build upon MSMQ, which means that your messages don't get lost since they are persisted to disk. Nevertheless the Framework has an impressive performance and an intuitive API.
John,
I agree that ASP.NET is not suitable for Async tasks as you have described them, nor should it be. It is designed as a web hosting platform, not a back of house processor.
We have had similar situations in the past and we have used a solution similar to what you have described. In summary, keep your WCF service under ASP.NET, use a "Queue" table with a Windows Service as the "QueueProcessor". The client should poll to see if work is done (or use messaging to notify the client).
We used a table that contained the process and it's information (eg InvoicingRun). On that table was a status (Pending, Running, Completed, Failed). The client would submit a new InvoicingRun with a status of Pending. A Windows service (the processor) would poll the database to get any runs that in the pending stage (you could also use SQL Notification so you don't need to poll. If a pending run was found, it would move it to running, do the processing and then move it to completed/failed.
In the case where the process failed fatally (eg DB down, process killed), the run would be left in a running state, and human intervention was required. If the process failed in an non-fatal state (exception, error), the process would be moved to failed, and you can choose to retry or have human intervantion.
If there were multiple processors, the first one to move it to a running state got that job. You can use this method to prevent the job being run twice. Alternate is to do the select then update to running under a transaction. Make sure either of these outside a transaction larger transaction. Sample (rough) SQL:
UPDATE InvoicingRun
SET Status = 2 -- Running
WHERE ID = 1
AND Status = 1 -- Pending
IF ##RowCount = 0
SELECT Cast(0 as bit)
ELSE
SELECT Cast(1 as bit)
Rob
Use a simple background tasks / jobs framework like Hangfire and apply these best practice principals to the design of the rest of your solution:
Keep all actions as small as possible; to achieve this, you should-
Divide long running jobs into batches and queue them (in a Hangfire queue or on a bus of another sort)
Make sure your small jobs (batched parts of long jobs) are idempotent (have all the context they need to run in any order). This way you don't have to use a quete which maintains a sequence; because then you can
Parallelise the execution of jobs in your queue depending on how many nodes you have in your web server farm. You can even control how much load this subjects your farm to (as a trade off to servicing web requests). This ensures that you complete the whole job (all batches) as fast and as efficiently as possible, while not compromising your cluster from servicing web clients.
Have thought about the use the Workflow Foundation instead of your custom implementation? It also allows you to persist states. Tasks could be defined as workflows in this case.
Just some thoughts...
Michael

Resources