suave icon indicating copy to clipboard operation
suave copied to clipboard

Graceful exit with an API call, or better ?

Open flotrek opened this issue 6 years ago • 3 comments

I'm trying to gracefully exit the webServer with a GET or POST to the the webServer itself.

Is there a way to execute code after a HTTP response has been given to the client to help me do that properly ?

Is there a nicer way to handle shutting down suave server from a CD pipeline ?

let app = 
    choose [
        path "/gracefulExit" >=> 
            request(fun r -> 
                fun () ->
                    Threading.Thread.Sleep(1000)
                    Log.Information("graceful exit...")
                    cancellationTokenSource.Cancel()                                         
                |> doAsyncTask |> Async.Start 
                OK "Initiating graceful exit"
                                       )]

flotrek avatar Sep 26 '19 11:09 flotrek

Not perfect but this may work.

open Suave.Sockets

let flush (ctx:HttpContext) =
  async{
    match! AsyncSocket.flush(ctx.connection) with
    | Choice1Of2 cn ->
      return Some { ctx with connection = cn }
    | _ -> return Some ctx //don't care we are shutting down anyways
  }

let shutdown (cts:CancellationTokenSource) (ctx:HttpContext) =
  async{
    do cts.Cancel()
    return Some ctx }

let test (cts:CancellationTokenSource) : WebPart = 
  path "/gracefulExit" >=> Successful.OK "Shutdown inititated" >=> flush >=> shutdown cts

It wouldn't be so graceful though, other requests being processed will be interrupted. Currently there is no built-in way of doing a truly graceful shutdown.

ademar avatar Sep 26 '19 15:09 ademar

The exit is graceful enough (with or without the flush by the way), but client still receives HTTP 503 instead of 200.

flotrek avatar Sep 26 '19 16:09 flotrek

Ah I see, it actually doesn't send any data down the pipe (at least here). I'll have to play more with it to see if it is possible,

ademar avatar Sep 26 '19 17:09 ademar