Run IHostedService on only one instance of a scaled out Azure App Service - asp.net-core

Is it possible to run an IHostedService on only one instance of a scaled out Azure App Service in ASP.NET Core? Or would the solution be to run this IHostedService in its own app service with one instance?
I have a BackgroundService that runs once a day and sends out reports via email. This service will run twice a day at the same time when my App Service is scaled out to 2 instances, resulting in two identical emails being sent.
How can I solve this problem?

It's better to break out things into separate apps, and that's the case here as well. If you only want one instance of your hosted service, you should break it out into a separate project and deploy one instance of that. If you deploy it inside your app, there will be an instance per instance of your app; there's no way around that, refer to this thread.
With Hosted Services, there is an instance running of that hosted service for every deployment of your website which can be an issue if you only want one instance of that “process” running at anytime. You can program around this by creating your own locking mechanism, but obviously webjobs gets this out of the box. So you can use webjob running as a singleton to achieve what you want. Refer to the article about Hosted Services In ASP.NET Core.

Related

Hangfire and main app in different applications

We have web application developed in .NET Core and is hosted on azure. We want to use HangFire for report scheduling.
Our application is multitenant so it will have load of its own, So I want to run these background processes into different server. HangFire has option of Placing Processing into Another Process as Using Console applications or Using Windows Services.
I have gone through HangFire Doc but there is no clear explanation of how this main application (which is .NET CORE) connects to this Console application?
https://docs.hangfire.io/en/latest/background-processing/placing-processing-into-another-process.html
I came across this question but still is not clear to me
How to run Hangfire as a separate process from the main web application?
Your AspNet .Net Core application (the hangfire client) will not communicate directly with the console application (the hangfire server).
Communication is done trhough the storage (the database) : client declares new tasks in the storage, and the server polls the storage (or is notified by the storage depending on the storage technology, like Redis) to execute the tasks.
You need to ensure communication of both client and server with the storage, but not between the client and the server.

Can Hangfire schedule jobs do this?

I am evaluating Hangfire for an upcoming ASP.net Core project that has several scheduled and reoccurring tasks that need to execute independently of users clicking on web pages. I know that HangFire can do this if the web application is started because a request has come in. I need to know whether or not HangFire can execute a scheduled task between being rebooted and the first web request coming in.
Example: Web server is rebooted at 11pm, and no web requests will come in to cause the web server to spin up until 5am the next morning. A scheduled task needs to be performed at 1AM. Will Hangfire execute this task even though the web application hasn't been started by an incoming request?
If it can, is there a certain setup I need to do to allow this?
Details, if needed:
We are going to be using Kestrel hosted in a windows service and sitting behind an NGINX reverse proxy. This setup could be modified if needed to make HangFire meet this requirement.
When running under IIS it would be a real problem, see Making ASP.NET application always running
But it should not be problem for ASP.NET CORE with kestrel, see
It is not necessary for ASP.NET Core, because application is exposed
by a console application that it already always on – there are no
timeouts, no suspends and other optimization techniques yet. All you
need to do is to use supervisor as written in the official docs for
Linux, or use Windows Service with automatic start time, when running
on Windows.

IIS Application Recycle drops static classes

I'm using Simple Injector in my WCF service. While running it from VS2010 everything is fine. However, when I publish it to my server using IIS 7, after some time (20 min, counted) my WCF loses all registered assemblies, modules, classes in container.
I guess IIS recycles the WCF Service Application Pool and drops my container registrations.
Can anyone help me on this?
While there exists many legitimate cases of using self-hosting WCF services, however, approaching self-hosting just because of IIS recycling may be counter productive.
Hosting in IIS gives you a lot benefit during development and daily operations, and I am not going to repeat what benefits which you could easily find out in google search.
So when IIS receive the first request to your application, it will launch a worker process named "w3wp.exe" according the settings in the application pool associated with your web app. And by default IIS will shutdown in 20 minutes of idle time. Check the Advanced Settings of the application pool, you will find a lot settings for the life cycle. You won't get such flexibility and robustness through self-hosting out of the box.
So basically you could have a few options provided you decide to stay with IIS hosting.
Change the Idle Time-out to 24-hours or even a month.
Write a small program or use cUrl to ping your application every 10 minute.
Leave it as it is
If you want to keep states during operations, save them in disk, then load them during next launch triggered by a request.

Where to initialize MassTransit in an Asp.Net MVC 4 application?

I have a simple solution with 3 projects:
Asp.Net MVC4 Web app - the main website
Console App - task runner
Console App - task runner
I wish to use MassTrasnsit to serve as a queue so that actions on the website (like send email) do not block the website, instead being published to the queue and taken care by the task runners.
My question is: Where should I initialize the queue, the web app, one of the task runners or create a separate console app for that?
ps. The console apps will be windows services when running on production servers.
As creating the queue is a one-off operation and you will probably want to tweak the default permissions, it would be best to create the queue in advance using a separate console app. Note that the publisher (the web app) and the consumers (the task runners) need a queue each, and that if they are on different servers then you will need to create the queues on each server.

WCF Service hosted in IIS - Can't seem to cache or retain state?

I'm trying to cache some application data that only needs to be instantiated when the application starts. I've tried using HttpRuntime.Cache, creating a static object that is instantiated only when the service starts, and I've tried making the service singleton and using global variables. Every time a new request hits the service I loose state... I could create the WCF service as a windows service I suppose, but I'd love to figure out what's happening here... I see that only one IIS worker process is spawning, but I'm guessing it's unloading and re-loading the service every time.
Am I missing some WCF configuration or possibly not setting it up right in IIS? It's running as a normal 2.0 website within IIS.
This my first post here, if someone can tell me how to post my app.config XML I will... I think stackoverflow is trying to parse it as HTML, it doesn't show up.
Thank you!
Tim
We use enterprise library caching with WCF services, works for us:
http://msdn.microsoft.com/en-us/library/dd203099.aspx
Edit
This answer is a bit old we have now stopped using Enterprise Library Caching, we use app fabric instead, see: http://msdn.microsoft.com/en-us/windowsserver/ee695849