Fiber: 馃悰 Shoutdown blocked after send file.

Created on 20 Oct 2020  路  8Comments  路  Source: gofiber/fiber

Fiber version

v2.1.0

Issue description

Cannot stop the server correctly. Just ouput server is stopping.

Code snippet

Save this code snippet as app.go.

package main

import (
    "log"
    "os"
    "os/signal"

    "github.com/gofiber/fiber/v2"
)

func main() {
    var app = fiber.New()

    app.Get("/", func(ctx *fiber.Ctx) (err error) {
        if err = ctx.SendFile("app.go"); err != nil {
            return
        }
        return
    })

    var err error
    go func() {
        if err = app.Listen(":3000"); err != nil {
            log.Fatal(err)
        }
    }()

    signalChanel := make(chan os.Signal, 1)
    signal.Notify(signalChanel, os.Interrupt)

    <-signalChanel

    log.Println("server is stopping")
    if err = app.Shutdown(); err != nil {
        log.Fatal(err)
    }
}
鈽笍 Bug

All 8 comments

Thanks for opening your first issue here! 馃帀 Be sure to follow the issue template! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

This is probably because you still have open connections attached to your server. Keep in mind that Shutdown() is basically a _graceful shutdown_ that does not accept new connections while finishing the onces that are open. I assume you are testing this with a modern browser, they keep connections alive by default. Try to use curl and it should shutdown directly.

PS: Or lower the IdleTimout in fiber.Config

var app = fiber.New(fiber.Config{
    IdleTimeout: time.Second * 5,
})

Add this line solve my issue.

HTTP header Connection: keep-alive got this error.

Is it possible add context to Shutdown like this: https://github.com/golang/go/blob/master/src/net/http/server.go#L2724.

So we can shutdown the server like this:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err = app.Shutdown(ctx); err != nil {
    logging.Error(err)
}

I don't think that is necessary

func main() {
    app := fiber.New()

    wait := make(chan bool)
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()

    go func() {
        select {
        case <-ctx.Done():
            if ctx.Err().Error() == "context deadline exceeded" {
                log.Fatal(app.Shutdown())
            }
            wait <- true
            break
        }
    }()

    time.Sleep(3 * time.Second)
    <-wait // for the goroutine we started earlier
}

The Connection general header controls whether or not the network connection stays open after the current transaction finishes. If the value sent is keep-alive, the connection is persistent and not closed, allowing for subsequent requests to the same server to be done.

In my case, the connection is idle, it is OK to close. Your code snippet will always panic.
Close idle connection is necessary after graceful shutdown. https://github.com/golang/go/blob/release-branch.go1.15/src/net/http/server.go#L2743

Unfortunately fasthttp havn't implement close idle connection function.

I don't think that is necessary


func main() {

  app := fiber.New()



  wait := make(chan bool)

  ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)

  defer cancel()



  go func() {

      select {

      case <-ctx.Done():

          if ctx.Err().Error() == "context deadline exceeded" {

              log.Fatal(app.Shutdown())

          }

          wait <- true

          break

      }

  }()



  time.Sleep(3 * time.Second)

  <-wait // for the goroutine we started earlier

}

@tosone @KoyamaSohei would you guys be able to help me create a cell phone app?

Feel free to re-open, seems answered 馃憤

PS: I don't have time to help with a cell phone app, sorry @johnuno11

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bashery picture bashery  路  4Comments

Aguezz picture Aguezz  路  4Comments

jeyraj picture jeyraj  路  4Comments

petersephrin picture petersephrin  路  4Comments

mayowa picture mayowa  路  3Comments