github.com/artisanhe/tools@v1.0.1-0.20210607022958-19a8fef2eb04/gin_app/gin.go (about) 1 package gin_app 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 "os" 8 "os/signal" 9 "syscall" 10 "time" 11 12 "github.com/gin-contrib/cors" 13 "github.com/gin-gonic/gin" 14 15 "github.com/artisanhe/tools/conf" 16 "github.com/artisanhe/tools/env" 17 ) 18 19 type GinApp struct { 20 Name string 21 IP string 22 Port int 23 SwaggerPath string 24 WithCORS bool 25 app *gin.Engine 26 } 27 28 func (a GinApp) DockerDefaults() conf.DockerDefaults { 29 return conf.DockerDefaults{ 30 "Port": 80, 31 "WithCORS": false, 32 } 33 } 34 35 func (a GinApp) MarshalDefaults(v interface{}) { 36 if g, ok := v.(*GinApp); ok { 37 if g.Name == "" { 38 g.Name = os.Getenv("PROJECT_NAME") 39 } 40 41 if g.SwaggerPath == "" { 42 g.SwaggerPath = "./swagger.json" 43 } 44 45 if g.Port == 0 { 46 g.Port = 80 47 } 48 } 49 } 50 51 func (a *GinApp) Init() { 52 if env.IsOnline() { 53 gin.SetMode(gin.ReleaseMode) 54 } 55 56 a.app = gin.New() 57 58 if a.WithCORS { 59 a.app.Use(cors.New(cors.Config{ 60 AllowAllOrigins: true, 61 AllowMethods: []string{"GET", "POST", "PUT", "HEAD", "DELETE", "PATCH"}, 62 AllowHeaders: []string{"Origin", "Content-Length", "Content-Type", "Authorization", "AppToken", "AccessKey", "Cookie"}, 63 AllowCredentials: true, 64 MaxAge: 12 * time.Hour, 65 })) 66 } 67 68 a.app.Use(gin.Recovery(), WithServiceName(a.Name), Logger()) 69 } 70 71 type GinEngineFunc func(router *gin.Engine) 72 73 func (a *GinApp) Register(ginEngineFunc GinEngineFunc) { 74 ginEngineFunc(a.app) 75 } 76 77 func (a *GinApp) Start() { 78 a.MarshalDefaults(a) 79 a.app.GET("/healthz", func(c *gin.Context) {}) 80 81 srv := &http.Server{ 82 Addr: a.getAddr(), 83 Handler: a.app, 84 } 85 86 go func() { 87 if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { 88 fmt.Fprintf(os.Stderr, "Server run failed[%s]\n", err.Error()) 89 os.Exit(1) 90 } 91 }() 92 93 quit := make(chan os.Signal, 1) 94 signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) 95 <-quit 96 97 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 98 defer cancel() 99 100 if err := srv.Shutdown(ctx); err != nil { 101 fmt.Printf("Server Shutdown on failed[%+v]\n", err) 102 } 103 104 time.Sleep(2 * time.Second) 105 fmt.Printf("Server exiting\n") 106 } 107 108 func (a GinApp) getAddr() string { 109 return fmt.Sprintf("%s:%d", a.IP, a.Port) 110 }