如何在Gin框架中添加后回调

时间:2017-11-30 09:53:09

标签: go go-gin

我需要在HTTP请求完全完成后用os.Exit(0)退出应用程序。我的应用程序询问另一台服务器是否需要升级,因此我需要退出以通过重新启动执行自我升级,但我不想破坏当前的HTTP请求。

当我尝试在c.Next()之后或处理程序函数结束时退出中间件时,浏览器会出错:localhost didn’t send any data

如何做到这一点?

2 个答案:

答案 0 :(得分:3)

正如您所说,您的程序在HTTP连接完全干净之前终止 - 您需要等待HTTP事务完成然后退出。幸运的是,由于Go 1.8 http.ServerShutdown method可以满足您的需求。

  

Shutdown正常关闭服务器而不会中断任何活动连接。关闭工作首先关闭所有打开的侦听器,然后关闭所有空闲连接,然后无限期地等待连接返回空闲然后关闭。

因此,一般方法是:

exitChan := make(chan struct{})

// Get a reference to exitChan to your handlers somehow

h := &http.Server{
    // your config
}
go func(){
    h.ListenAndServe() // Run server in goroutine so as not to block
}()

<-exitChan // Block on channel
h.Shutdown(nil) // Shutdown cleanly with a timeout of 5 seconds

然后在需要关闭时处理程序/中间件中的exitChan <- struct{}{}

另请参阅:How to stop http.ListenAndServe()

答案 1 :(得分:1)

您可以在其github存储库上参考此示例:
graceful-shutdown

package main

import (
    "context"
    "log"
    "net/http"
    "os"
    "os/signal"
    "time"

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

func main() {
    router := gin.Default()
    router.GET("/", func(c *gin.Context) {
        time.Sleep(5 * time.Second)
        c.String(http.StatusOK, "Welcome Gin Server")
    })

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

    go func() {
        // service connections
        if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
            log.Fatalf("listen: %s\n", err)
        }
    }()

    // Wait for interrupt signal to gracefully shutdown the server with
    // a timeout of 5 seconds.
    quit := make(chan os.Signal)
    signal.Notify(quit, os.Interrupt)
    <-quit
    log.Println("Shutdown Server ...")

    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    if err := srv.Shutdown(ctx); err != nil {
        log.Fatal("Server Shutdown:", err)
    }
    log.Println("Server exiting")
}