• With issues:
  • Use the search tool before opening a new issue.
  • Please provide source code and commit sha if you found a bug.
  • Review existing issues and provide feedback or react to them.

Description

I think gin should give a method go gracefully shutdown server; Althrouth we can use http.server to implement it, but it is not beautiful.

How to reproduce

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    g := gin.Default()
    g.GET("/hello/:name", func(c *gin.Context) {
        c.String(200, "Hello %s", c.Param("name"))
    })
    // g.Run(":9000")

       g.GracefulRun(:9000)
}

Expectations

$ curl http://localhost:8201/hello/world
Hello world

Actual result

$ curl -i http://localhost:8201/hello/world
<YOUR RESULT>

Environment

  • go version:
  • gin version (or commit ref):
  • operating system:

Comment From: jincheng9

@lowang-bh Currently you can use third-party solution to do this. Gin may implement in future release.

Comment From: lowang-bh

@lowang-bh Currently you can use third-party solution to do this. Gin may implement in future release.

Thanks for your reply.

Comment From: jincheng9

@lowang-bh cheers, many 3rd solutions can implement this with Gin. such as endless.

Comment From: ex-tag

If Gin is going to provide a Run method, it should also provide a Shutdown method. Sometimes you want to stop the server from running from within the program, and there is no way to do that.

Example source code changes might be...

type Engine struct {
  Server http.Server
}

// Run attaches the router to a http.Server and starts listening and serving HTTP requests.
// It is a shortcut for http.ListenAndServe(addr, router)
// Note: this method will block the calling goroutine indefinitely unless an error happens.
func (engine *Engine) Run(addr ...string) (err error) {
  defer func() { debugPrintError(err) }()
  if engine.isUnsafeTrustedProxies() {
    debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" +
       "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.")
  }

  address := resolveAddress(addr)
  debugPrint("Listening and serving HTTP on %s\n", address)

  engine.Server = &http.Server{
    Addr:  address,
    Handler: engine
  }

  err = engine.Server.ListenAndServe()
  return
}

func (engine *Engine) Stop() (err error) {
  err := engine.Server.Shutdown(gin.Context)
  return
}

Comment From: ex-tag

Also for someone else that might be struggling to understand how @appleboy graceful shutdown examples work with gin.context.

  1. Create a notifier context, and block until a system call (signal interrupt) is sent
// Line 18
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)

// Line 41
<-ctx.Done()
  1. Once the signal context is done (unblocks), then create a wait context and pass that to the server
// Line 21
router := gin.Default()

// Line 27
srv := &http.Server{
  Addr:    ":8080",
  Handler: router,
}

// Line 49
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)

// Line 51
if err := srv.Shutdown(ctx); err != nil {
  log.Fatal("Server forced to shutdown: ", err)
}
  1. context *gin.Context is a context created for each instance of a route. So when the server shuts down, it will close each route and it's associated context.

Comment From: FlyingOnion

Great solutions. I want to provide a suggestion too. If gin implements a graceful shutdown method, please also provide an option to not enable the method. This could avoid conflicts with users' own solutions. Maybe there will be two channels catching signals and however you press Ctrl+C the program will not exit. ~~So glad to see that occurs.~~

Comment From: appleboy

I write the simple library for graceful shutdown. See: https://github.com/appleboy/graceful

Comment From: cedric-appdirect

I have created a PR to add graceful shutdown to gin: https://github.com/gin-contrib/graceful/pull/2 . I would appreciate any feedback on it as that repository doesn't seems to receive any attention at the moment.

Comment From: Bluebugs

The PR has been approved and merged. There is now a working https://github.com/gin-contrib/graceful implementation available. I would think this should close this issue.

Comment From: appleboy

@Bluebugs Can you help to write documentation in gin-contrib/graceful?