singleflight

package
v1.5.5 Latest Latest
Warning

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

Go to latest
Published: Jun 24, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package singleflight provides request-coalescing middleware for celeris.

When several identical requests arrive concurrently, only the first (the "leader") executes the handler chain; the rest (the "waiters") block until the leader finishes and then receive a copy of its response. This absorbs thundering-herd bursts on hot endpoints so they hit the backend once.

Install it with New, optionally passing a Config. The zero-value configuration deduplicates on method + path + sorted query string + Authorization + Cookie, so requests from different authenticated users are never coalesced. Use Config.KeyFunc to change the key, and Config.Skip or Config.SkipPaths to exclude requests (for example non-idempotent methods or large-response endpoints). Waiter responses carry an "x-singleflight: HIT" header.

server.Use(singleflight.New())

Singleflight buffers the leader's response, so install it after timeout middleware and before response transforms such as compress or etag. It is intended for idempotent reads; a custom KeyFunc that returns user-specific data must incorporate user identity to avoid cross-user leakage.

Documentation

Full guides and examples: https://goceleris.dev/docs/middleware-traffic

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(config ...Config) celeris.HandlerFunc

New creates a singleflight middleware with the given config.

Example
package main

import (
	"github.com/goceleris/celeris/middleware/singleflight"
)

func main() {
	// Deduplicate concurrent identical GET requests using the default key
	// (method + path + sorted query string).
	// s := celeris.New()
	// s.Use(singleflight.New())
	_ = singleflight.New()
}
Example (CustomKey)
package main

import (
	"github.com/goceleris/celeris"
	"github.com/goceleris/celeris/middleware/singleflight"
)

func main() {
	// Use only the path as the deduplication key, ignoring query parameters.
	_ = singleflight.New(singleflight.Config{
		KeyFunc: func(c *celeris.Context) string {
			return c.Method() + "\x00" + c.Path()
		},
	})
}
Example (SkipNonGET)
package main

import (
	"github.com/goceleris/celeris"
	"github.com/goceleris/celeris/middleware/singleflight"
)

func main() {
	// Only deduplicate GET and HEAD requests (recommended).
	_ = singleflight.New(singleflight.Config{
		Skip: func(c *celeris.Context) bool {
			m := c.Method()
			return m != "GET" && m != "HEAD"
		},
	})
}

Types

type Config

type Config struct {
	// Skip defines a function to skip this middleware for certain requests.
	Skip func(c *celeris.Context) bool

	// SkipPaths lists paths to skip (exact match).
	SkipPaths []string

	// KeyFunc extracts the deduplication key from the request. Requests
	// with the same key that arrive while a leader request is in-flight
	// are coalesced — waiters receive a copy of the leader's response.
	//
	// Default: method + "\x00" + path + "\x00" + sorted-query-string
	// + "\x00" + Authorization header + "\x00" + Cookie header. The
	// Authorization and Cookie components ensure that requests from
	// different authenticated users produce different keys, preventing
	// cross-user data leakage. Unauthenticated requests (no auth/cookie
	// headers) still coalesce normally.
	//
	// If you provide a custom KeyFunc, ensure it incorporates user
	// identity for any endpoint that returns user-specific data.
	KeyFunc func(c *celeris.Context) string
}

Config defines the singleflight middleware configuration.

Jump to

Keyboard shortcuts

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