Skip to content

Commit

Permalink
upgrade (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
pkieltyka authored Feb 12, 2024
1 parent cd10c59 commit 57187fb
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 426 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ prevent a stampede scenario on your handler.
to not include anything sensitive or user specific. In the case you require user-specific
stampede handlers, make sure you pass a custom `keyFunc` to the `stampede.Handler` and
split the cache by an account's id.

See [example](_example/with_key.go) for a variety of examples.


Expand Down
16 changes: 16 additions & 0 deletions _example/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module example

go 1.21.7

replace github.com/go-chi/stampede => ../

require (
github.com/go-chi/chi/v5 v5.0.11
github.com/go-chi/stampede v0.5.1
)

require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/goware/singleflight v0.2.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
)
18 changes: 18 additions & 0 deletions _example/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA=
github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.2.0 h1:tV1g1XENQ8ku4Bq3K9ub2AtgG+p16SmzeMSGTwrOKdE=
github.com/go-chi/cors v1.2.0/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/goware/singleflight v0.2.0 h1:e/hZsvNmbLoiZLx3XbihH01oXYA2MwLFo4e+N017U4c=
github.com/goware/singleflight v0.2.0/go.mod h1:SsAslCMS7HizXdbYcBQRBLC7HcNmFrHutRt3Hz6wovY=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
13 changes: 10 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
module github.com/go-chi/stampede

go 1.16
go 1.20

require (
github.com/cespare/xxhash/v2 v2.1.2
github.com/cespare/xxhash/v2 v2.2.0
github.com/go-chi/cors v1.2.0
github.com/hashicorp/golang-lru v0.5.5-0.20200511160909-eb529947af53
github.com/goware/singleflight v0.2.0
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/stretchr/testify v1.5.1
)

require (
github.com/davecgh/go-spew v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v2 v2.2.2 // indirect
)
10 changes: 6 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-chi/cors v1.2.0 h1:tV1g1XENQ8ku4Bq3K9ub2AtgG+p16SmzeMSGTwrOKdE=
github.com/go-chi/cors v1.2.0/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/hashicorp/golang-lru v0.5.5-0.20200511160909-eb529947af53 h1:mcyf48FjrlX8JRXvy5v3LPeXBv+Um6WvoKS+kknfgIk=
github.com/hashicorp/golang-lru v0.5.5-0.20200511160909-eb529947af53/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/goware/singleflight v0.2.0 h1:e/hZsvNmbLoiZLx3XbihH01oXYA2MwLFo4e+N017U4c=
github.com/goware/singleflight v0.2.0/go.mod h1:SsAslCMS7HizXdbYcBQRBLC7HcNmFrHutRt3Hz6wovY=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
26 changes: 10 additions & 16 deletions http.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ package stampede

import (
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"net/http"
"strings"
"time"
Expand All @@ -27,8 +25,8 @@ func Handler(cacheSize int, ttl time.Duration, paths ...string) func(next http.H
// Read the request payload, and then setup buffer for future reader
var buf []byte
if r.Body != nil {
buf, _ = ioutil.ReadAll(r.Body)
r.Body = ioutil.NopCloser(bytes.NewBuffer(buf))
buf, _ = io.ReadAll(r.Body)
r.Body = io.NopCloser(bytes.NewBuffer(buf))
}

// Prepare cache key based on request URL path and the request data payload.
Expand Down Expand Up @@ -77,7 +75,7 @@ func HandlerWithKey(cacheSize int, ttl time.Duration, keyFunc func(r *http.Reque
}

func stampede(cacheSize int, ttl time.Duration, keyFunc func(r *http.Request) uint64) func(next http.Handler) http.Handler {
cache := NewCache(cacheSize, ttl, ttl*2)
cache := NewCacheKV[uint64, responseValue](cacheSize, ttl, ttl*2)

return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand All @@ -89,7 +87,7 @@ func stampede(cacheSize int, ttl time.Duration, keyFunc func(r *http.Request) ui
first := false

// process request (single flight)
val, err := cache.GetFresh(r.Context(), key, func(ctx context.Context) (interface{}, error) {
respVal, err := cache.GetFresh(r.Context(), key, func() (responseValue, error) {
first = true
buf := bytes.NewBuffer(nil)
ww := &responseWriter{ResponseWriter: w, tee: buf}
Expand All @@ -116,22 +114,18 @@ func stampede(cacheSize int, ttl time.Duration, keyFunc func(r *http.Request) ui

// handle response for other listeners
if err != nil {
// TODO: perhaps just log error and execute standard handler..?
panic(fmt.Sprintf("stampede: fail to get value, %v", err))
}

resp, ok := val.(responseValue)
if !ok {
panic("stampede: handler received unexpected response value type")
}

if resp.skip {
if respVal.skip {
return
}

header := w.Header()

nextHeader:
for k := range resp.headers {
for k := range respVal.headers {
for _, match := range stripOutHeaders {
// Prevent any header in stripOutHeaders to override the current
// value of that header. This is important when you don't want a
Expand All @@ -142,11 +136,11 @@ func stampede(cacheSize int, ttl time.Duration, keyFunc func(r *http.Request) ui
continue nextHeader
}
}
header[k] = resp.headers[k]
header[k] = respVal.headers[k]
}

w.WriteHeader(resp.status)
w.Write(resp.body)
w.WriteHeader(respVal.status)
w.Write(respVal.body)
})
}
}
Expand Down
102 changes: 0 additions & 102 deletions singleflight/singleflight.go

This file was deleted.

Loading

0 comments on commit 57187fb

Please sign in to comment.