Finish current requests when stopping self-hosted owin server

前端 未结 1 1001
暗喜
暗喜 2021-01-05 23:17

I have OWIN server as part of console app. You can see the main method here:

class Program
{
    public static ManualResetEventSlim StopSwitch = new ManualRe         


        
相关标签:
1条回答
  • 2021-01-05 23:38

    I ended with the suggested approach with the middleware:

    public class ShutDownMiddleware
    {
        private readonly Func<IDictionary<string, object>, Task> next;
        private static int requestCount = 0;
        private static bool shutDownStateOn = false;
    
        public static void ShutDown()
        {
            shutDownStateOn = true;
        }
    
        public static int GetRequestCount()
        {
            return requestCount;
        }
    
        public ShutDownMiddleware(Func<IDictionary<string, object>, Task> next)
        {
            this.next = next;
        }
    
        public async Task Invoke(IDictionary<string, object> environment)
        {
            if (shutDownStateOn)
            {
                environment["owin.ResponseStatusCode"] = HttpStatusCode.ServiceUnavailable;
                return;
            }
    
            Interlocked.Increment(ref requestCount);
            try
            {
                await next.Invoke(environment);
            }
            finally
            {
                Interlocked.Decrement(ref requestCount);
            }
        }
    }
    

    This is registered as a first middleware in the pipeline and in the main method of program I can use it like this:

    public class Program
    {
        public static ManualResetEventSlim StopSwitch = new ManualResetEventSlim();
    
        static void Main(string[] args)
        {
            Console.CancelKeyPress += (s, a) =>
            {
                a.Cancel = true;
                StopSwitch.Set();
            };
    
            using (WebApp.Start<Startup>("http://+:8080/"))
            {
                Console.WriteLine("Server is running...");
                Console.WriteLine("Press CTRL+C to stop it.");
                StopSwitch.Wait();
                Console.WriteLine("Server is stopping...");
                ShutDownMiddleware.ShutDown();
                while (ShutDownMiddleware.GetRequestCount() != 0)
                {
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                }
            }
        }
    }
    

    I also found this: https://katanaproject.codeplex.com/workitem/281 They are talking about similar approach.

    0 讨论(0)
提交回复
热议问题