-1

I'm going to try to simplify this,

As part of an ASP.NET Core Web Api (.Net Core 2.2), I am working to achieve a taxi dispatcher background service that runs indefinitely and handles races -> assigns drivers to races, continuously fetch new drivers on the area and assign to races from closest to furthest accordingly (the service reads and writes to different Sql database tables). I created the background service as a hosted service that does all of the above whenever there are races available and handle each race in a new background thread. The api runs on a ftp server on IIS.

Problem: It works fine at the beginning but sometimes the service somehow times out and won't handle any incoming races and I have to stop the api and restart it, yikes, which isn't the behavior I want since I want my xamarin-forms app to be responsive and receive races in real time.

After I wrote the service, I started questioning my implementation and I came across terms like Background worker, Microservices and Worker services.. and now I'm more confused on what to fix or how to solve the problem, and if there is a better approach to this.

I use clean architecture design pattern in my Web Api. This is how I register my background service on Program.cs file:

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .ConfigureServices(services =>
                {
                    //Some workaround to use the hostedservice as an API
                    //see https://github.com/dotnet/extensions/issues/553
                    services.AddSingleton<BackgroundManagerService>();
                    services.AddSingleton<IHostedService>(p => p.GetService<BackgroundManagerService>());
                })
                .ConfigureLogging(logging =>
                {
                    logging.ClearProviders();
                    logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); //LogLevel.Information
                })
                .UseNLog();  // NLog: Setup NLog for Dependency injection;

Help is appreciated!

Anass
  • 301
  • 1
  • 3
  • 13
  • 2
    Do you realize you haven't asked anything? – Gusman Jun 28 '20 at 15:55
  • @Gusman I asked if there is a better implementation for what I am trying to achieve (paragraph 3), I'm a noobie to such advanced senario in my opinion :) – Anass Jun 28 '20 at 15:59
  • 1
    IIS will control the lifetime of your app; it will start the process and will terminate the application pool if the app is idle. Only incoming requests will cause IIS to start the app then. There are a few ways to control this within IIS but I haven’t had a real success in keeping an app always running on IIS. – poke Jun 28 '20 at 16:01
  • @poke There is a way, but it's really crappy: create a static timer that queries your own application each 5-10 minutes, that will prevent the application to be unloaded. – Gusman Jun 28 '20 at 16:04
  • @poke exactly, it does crash the app pool frequently if the service doesn't terminate (since I don't want to shutdown -> I want it to stay alive and handle races). I read the IIS documentation and couldn't figure out how to refactor my code to keep the service alive. I also recently signed up for an azure account to see if it is the same case but still hoping to run it on iis – Anass Jun 28 '20 at 16:08
  • @Gusman thank you for the proposition, I will give it a shot. I hoping to be pointed out to an alternative implementation of the whole service (hosted service) because as of now I am pretty sure I am doing it wrong – Anass Jun 28 '20 at 16:16
  • @Anass It was a comment for poke, I would avoid that approach as much as you can. the proper way is to create a microservice: a standalone executable that takes care of these things. – Gusman Jun 28 '20 at 16:18
  • @Gusman right, thank you for the clarification. I'm still at the beginning of the learning curve of .net core. I appreciate the help. – Anass Jun 28 '20 at 16:35
  • 1
    Yeah, the “recommended” (as in: working) way to solve this is to host your app as a Windows service instead of through IIS. – poke Jun 28 '20 at 19:35

1 Answers1

1

I ran into similar issues at work using Hangfire. While you can mess around with idle timeouts and app initializers (https://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html just as an example) we ultimately moved everything into a .NET Core Worker Service and hosted it as a Windows service.

https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-3.1&tabs=visual-studio

That is the approach I would suggest, it's worked out very well.

Julian
  • 36
  • 2
  • Thank you @julian for the kind answer and for pointing out your suggestion. I already started reading about Worker Services last week and I should be on my way to achieve what I want to do. I will mark this an answer as soon as I can get demo with the behavior up and running. – Anass Jun 28 '20 at 16:41