14

We have ASP.NET Core application used internally which are used during office hours and a batch that should be processed 3 AM every morning which is scheduled by HangFire like this:

RecurringJob.AddOrUpdate(
                () => MyBatch(),
                "0 0 3 1/1 *");

The problem is that the Application Pool goes to sleep and the batch isn’t processed if the site isn’t manually started (by going to the website usually).

I have searched SO and tampered with these settings in the Application Pool but with no success: enter image description here

Some sources that I used to modify the settings:

The Application Pool is used by a total of 7 applications (all being inactive during night when the batch should be processed). The used Application Pool uses .NET CLR Version 2.0. I'm using IIS version 10.0.17134.1.

How can I make the Application Pool stay active so the batch can be invoked regularly every morning?

Westerlund.io
  • 2,743
  • 5
  • 30
  • 37
  • 1
    According to my understanding the settings you have should work. Have you tried moving it to its own application pool ? – Pieter Alberts Jul 17 '18 at 05:11
  • Thanks for your comment @PieterAlberts! I have now created a new Application Pool (AP) for this application. I noticed that the `.NET CLR Version` on the previous AP was `2.0`. I’m not sure if that makes any difference but according to https://stackoverflow.com/questions/49185512/what-is-the-effect-of-setting-or-not-net-clr-version-in-asp-net-core I can use `No managed code` for Core applications which I will test out in this AP together with the same changes as in the previous AP. – Westerlund.io Jul 18 '18 at 09:19
  • @PieterAlberts No luck when moving the site to it's own AP =/ – Westerlund.io Jul 19 '18 at 16:24
  • that really sucks. Well i am fresh out of ideas... If you really need this solved maybe add a +50 bounty on your question? – Pieter Alberts Jul 20 '18 at 04:41
  • At this [post](https://stackoverflow.com/questions/47509674/recycle-of-app-pool-kills-kestrel-but-does-not-restart) they explain that the `Kestrel` process gets killed when the `IIS` application pool gets recycled and that `IIS` might get started again, but for `Kestrel` this is only when a new request comes in (via `IIS`). Besides the advice there to move your application to a scheduler or windows service, in the meantime as a quick and dirty **workaround** you might schedule a `CURL` or `PowerShell` script to make a web request to your website a the desired time as a 'wake-up call'. – pfx Jul 25 '18 at 18:06

5 Answers5

7

I ran into the same issue where my ASP.NET core application goes into idle even with "AlwaysRunning" as start mode for the app pool, "Preload Enabled" set to true for the site, and idle timeout set to 0. I got it to work by installing the Application Initialization module and setting the .NET CLR version to v4.0. Don't use the "No Managed Code" as that would prevent the Always Running from triggering the app start.

I wrote a blog post on this explaining in more details the steps I took to get the app to run continuously.

Tai Bo
  • 321
  • 4
  • 8
2

They got documentation on how to set up service to run without stopping.

http://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html#enabling-service-auto-start

My experience (with older IIS versions 7.5, 8.0) is that it works, but not for app pool recycle/domain unload. Workaround for me was to send init request on the application_end event.

wolszakp
  • 1,109
  • 11
  • 25
0

As above - you need to enable the Service Autostart - in addition to this, if you hit multiple exceptions, I have found that the Rapid Fail Protection has shut down Application pools in the past when using HangFire. So it's also worth disabling (or increasing to reasonable limits) this on the application pool.

Phil Golding
  • 433
  • 3
  • 10
0

I'd suggest you put in your process a single call to the HTTP address first, just like a ping, that would be enought to trigger the site startup if it isn't running for some reason.

One other thing is that, by microsoft's description at MSDN the "AlwaysRunning" option would be:

"Specifies that the Windows Process Activation Service (WAS) will always start the application pool. This behavior allows an application to load the operating environment before any serving any HTTP requests, which reduces the start-up processing for initial HTTP requests for the application."

That may be, to produce the compilation of web pages that is done on the first call to be done before any request coming, but may not actually run the application at all times.

SammuelMiranda
  • 420
  • 4
  • 29
0

I am on a Shared IIS Hosting with no access to most settings. What I did is add a Recurring Job that would be triggered in minute interval less than the IIS Timeout/Idle.

RecurringJob.AddOrUpdate<IMyKeepAliveService>("KeepHangFireAlive", svc => svc.KeepHangFireAlive(URL_TO_SELF), "*/4 * * * *");

The above CRON is enough to prevent IIS App pool from going to sleep. I use RestSharp to make a tiny ping/GET request to "Self".

hubert17
  • 285
  • 5
  • 8