Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend default timeout on certain path patterns #53

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

etiennemarais
Copy link

Summary

We ran into a use case where certain longer running endpoints needed their timeout to be extended beyond what the rest of the API required due to longer running legacy processes that couldn't be changed for backwards compatibility. There was a limitation in this middleware package that we couldn't easily extend certain paths from the normal timeout.

Extending certain paths, path patterns or lists of paths allows us to configure endpoints in a more controlled way, instead of updating the whole app to allow longer running timeouts.

Changes

  • Added a functional option to set the extended default timeout:
func WithExtendedTimeout(extendedTimeout time.Duration) Option
  • Added a functional option to set the list of paths that can be extended:
func WithExtendedPaths(extendedPaths []string) Option
  • Added a check against the set list of path patterns which will extend the timeout for that path only.
  • If no extended paths have been set, the normal timeout will be used.
  • Added tests to cover success and timeout states when using extended options.
  • Added example and readme updates

Example Usage

package main

import (
	"log"
	"net/http"
	"time"

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

func testResponse(c *gin.Context) {
	c.String(http.StatusRequestTimeout, "timeout")
}

func extendedTimeoutMiddleware() gin.HandlerFunc {
	return timeout.New(
		timeout.WithTimeout(200*time.Millisecond),          // Default timeout on all routes
		timeout.WithExtendedTimeout(1000*time.Millisecond), // Extended timeout on pattern based routes
		timeout.WithExtendedPaths([]string{"/ext.*"}),      // List of patterns to allow extended timeouts
		timeout.WithHandler(func(c *gin.Context) {
			c.Next()
		}),
		timeout.WithResponse(testResponse),
	)
}

func main() {
	r := gin.New()
	r.Use(extendedTimeoutMiddleware())
	r.GET("/extended", func(c *gin.Context) {
		time.Sleep(800 * time.Millisecond)
		c.Status(http.StatusOK)
	})

	if err := r.Run(":8080"); err != nil {
		log.Fatal(err)
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant