timeout

package module
v0.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2025 License: MIT Imports: 10 Imported by: 38

README

gin-timeout

golang-ci

Timeout Middleware for Gin framework

Thanks

Inspired by golang source code http.TimeoutHandler

Usage

Download and install using go module:

export GO111MODULE=on
go get github.com/vearne/gin-timeout
Notice:
  • If the handler supports to be canceled, you need to pass gin.Context.Request.Context() as parameter.

  • If you want to get the status code of the response in middleware, you should put the middleware before the timeout middleware.

package main

import (
	"net/http"
	"net/http/httptest"
	"time"

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

func main() {
	req, _ := http.NewRequest("GET", "/test", nil)

	engine := gin.New()
	engine.Use(func(c *gin.Context) {
		c.Next()
		println("middleware code: ", c.Writer.Status())
	})

	engine.Use(timeout.Timeout(timeout.WithTimeout(10 * time.Second)))
	
	engine.GET("/test", func(c *gin.Context) {
		c.Status(http.StatusBadRequest)
	})
	rr := httptest.NewRecorder()
	engine.ServeHTTP(rr, req)

	println("response code: ", rr.Code)
}
Example

more example

package main

import (
	"context"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/vearne/gin-timeout"
	"io/ioutil"
	"log"
	"net/http"
	"time"
)

func main() {
	// create new gin without any middleware
	engine := gin.Default()

	defaultMsg := `{"code": -1, "msg":"http: Handler timeout"}`
	// add timeout middleware with 2 second duration
	engine.Use(timeout.Timeout(
		timeout.WithTimeout(2*time.Second),
		timeout.WithErrorHttpCode(http.StatusRequestTimeout), // optional
		timeout.WithDefaultMsg(defaultMsg),                   // optional
		timeout.WithCallBack(func(r *http.Request) {
			fmt.Println("timeout happen, url:", r.URL.String())
		}),
		timeout.WithGinCtxCallBack(func(c *gin.Context) {
			fmt.Println("timeout happen, url:", c.Request.URL.String())
		}))) // optional

	// create a handler that will last 1 seconds
	engine.GET("/short", short)

	// create a handler that will last 5 seconds
	engine.GET("/long", long)

	// create a handler that will last 5 seconds but can be canceled.
	engine.GET("/long2", long2)

	// create a handler that will last 20 seconds but can be canceled.
	engine.GET("/long3", long3)

	engine.GET("/boundary", boundary)

	// run the server
	log.Fatal(engine.Run(":8080"))
}

func short(c *gin.Context) {
	time.Sleep(1 * time.Second)
	c.JSON(http.StatusOK, gin.H{"hello": "short"})
}

func long(c *gin.Context) {
	time.Sleep(3 * time.Second)
	c.JSON(http.StatusOK, gin.H{"hello": "long"})
}

func boundary(c *gin.Context) {
	time.Sleep(2 * time.Second)
	c.JSON(http.StatusOK, gin.H{"hello": "boundary"})
}

func long2(c *gin.Context) {
	if doSomething(c.Request.Context()) {
		c.JSON(http.StatusOK, gin.H{"hello": "long2"})
	}
}

func long3(c *gin.Context) {
	// request a slow service
	// see  https://github.com/vearne/gin-timeout/blob/master/example/slow_service.go
	url := "http://localhost:8882/hello"
	// Notice:
	// Please use c.Request.Context(), the handler will be canceled where timeout event happen.
	req, _ := http.NewRequestWithContext(c.Request.Context(), http.MethodGet, url, nil)
	client := http.Client{Timeout: 100 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		// Where timeout event happen, a error will be received.
		fmt.Println("error1:", err)
		return
	}
	defer resp.Body.Close()
	s, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("error2:", err)
		return
	}
	fmt.Println(s)
}

// A cancelCtx can be canceled.
// When canceled, it also cancels any children that implement canceler.
func doSomething(ctx context.Context) bool {
	select {
	case <-ctx.Done():
		fmt.Println("doSomething is canceled.")
		return false
	case <-time.After(5 * time.Second):
		fmt.Println("doSomething is done.")
		return true
	}
}
Thanks

jetbrains

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Timeout

func Timeout(opts ...Option) gin.HandlerFunc

Types

type BaseResponse added in v0.2.1

type BaseResponse struct {
	Code        int
	Content     any
	ContentType string
}

func (*BaseResponse) GetCode added in v0.2.1

func (r *BaseResponse) GetCode(c *gin.Context) int

func (*BaseResponse) GetContent added in v0.2.1

func (r *BaseResponse) GetContent(c *gin.Context) any

func (*BaseResponse) GetContentType added in v0.2.1

func (r *BaseResponse) GetContentType(c *gin.Context) string

func (*BaseResponse) SetCode added in v0.2.1

func (r *BaseResponse) SetCode(code int)

func (*BaseResponse) SetContent added in v0.2.1

func (r *BaseResponse) SetContent(content any)

func (*BaseResponse) SetContentType added in v0.2.1

func (r *BaseResponse) SetContentType(contentType string)

type CallBackFunc added in v0.0.6

type CallBackFunc func(*http.Request)

type GinCtxCallBackFunc added in v0.1.8

type GinCtxCallBackFunc func(*gin.Context)

type Option added in v0.0.6

type Option func(*TimeoutWriter)

func WithCallBack added in v0.0.6

func WithCallBack(f CallBackFunc) Option

WithCallBack Optional parameters

func WithContentType added in v0.2.1

func WithContentType(ct string) Option

WithContentType Optional parameters

func WithDefaultMsg added in v0.0.6

func WithDefaultMsg(resp interface{}) Option

WithDefaultMsg Optional parameters

func WithErrorHttpCode added in v0.0.6

func WithErrorHttpCode(code int) Option

WithErrorHttpCode Optional parameters

func WithGinCtxCallBack added in v0.1.8

func WithGinCtxCallBack(f GinCtxCallBackFunc) Option

WithGinCtxCallBack Optional parameters

func WithResponse added in v0.2.1

func WithResponse(resp Response) Option

func WithTimeout added in v0.0.6

func WithTimeout(d time.Duration) Option

type PanicInfo added in v0.2.2

type PanicInfo struct {
	Value any    `json:"value"`
	Stack string `json:"stack"`
}

type Response added in v0.2.1

type Response interface {
	GetCode(c *gin.Context) int
	GetContent(c *gin.Context) any
	GetContentType(c *gin.Context) string
	SetCode(int)
	SetContent(any)
	SetContentType(string)
}

type TimeoutOptions added in v0.0.6

type TimeoutOptions struct {
	CallBack       CallBackFunc
	GinCtxCallBack GinCtxCallBackFunc
	Timeout        time.Duration
	Response       Response
}

type TimeoutWriter

type TimeoutWriter struct {
	gin.ResponseWriter

	TimeoutOptions // TimeoutOptions in options.go
	// contains filtered or unexported fields
}

func (*TimeoutWriter) Header

func (tw *TimeoutWriter) Header() http.Header

func (*TimeoutWriter) Size added in v0.1.2

func (tw *TimeoutWriter) Size() int

func (*TimeoutWriter) Status added in v0.2.0

func (tw *TimeoutWriter) Status() int

func (*TimeoutWriter) Write

func (tw *TimeoutWriter) Write(b []byte) (int, error)

func (*TimeoutWriter) WriteHeader

func (tw *TimeoutWriter) WriteHeader(code int)

func (*TimeoutWriter) WriteHeaderNow

func (tw *TimeoutWriter) WriteHeaderNow()

Directories

Path Synopsis
example
custom_response command
file_server command
normal command
panic command
redirect command
slow_service command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL