Skip to content

Commit

Permalink
add/use new longest-match router
Browse files Browse the repository at this point in the history
  • Loading branch information
jranson committed Aug 12, 2024
1 parent d9885f5 commit f184a81
Show file tree
Hide file tree
Showing 17 changed files with 388 additions and 191 deletions.
8 changes: 4 additions & 4 deletions pkg/backends/backends_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import (

ho "github.com/trickstercache/trickster/v2/pkg/backends/healthcheck/options"
bo "github.com/trickstercache/trickster/v2/pkg/backends/options"
"github.com/trickstercache/trickster/v2/pkg/router"
"github.com/trickstercache/trickster/v2/pkg/router/lm"
)

func TestBackends(t *testing.T) {

cl, _ := New("test1", bo.New(), nil, router.NewRouter(), nil)
cl, _ := New("test1", bo.New(), nil, lm.NewRouter(), nil)
o := Backends{"test1": cl}

c := o.Get("test1")
Expand Down Expand Up @@ -77,11 +77,11 @@ func TestStartHealthChecks(t *testing.T) {
// 1: rule / Virtual provider
o1 := bo.New()
o1.Provider = "rule"
c1, _ := New("test1", o1, nil, router.NewRouter(), nil)
c1, _ := New("test1", o1, nil, lm.NewRouter(), nil)

// 2: non-virtual provider with no health check options
o2 := bo.New()
c2, _ := New("test2", o2, nil, router.NewRouter(), nil)
c2, _ := New("test2", o2, nil, lm.NewRouter(), nil)

b := Backends{"test1": c1}
_, err := b.StartHealthChecks(nil)
Expand Down
2 changes: 1 addition & 1 deletion pkg/backends/reverseproxy/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (c *Client) DefaultPathConfigs(o *bo.Options) map[string]*po.Options {
"/-" + strings.Join(am, "-"): {
Path: "/",
HandlerName: "proxy",
Methods: methods.AllHTTPMethods(),
Methods: am,
MatchType: matching.PathMatchTypePrefix,
MatchTypeName: "prefix",
},
Expand Down
4 changes: 2 additions & 2 deletions pkg/backends/timeseries_backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ import (
"testing"

bo "github.com/trickstercache/trickster/v2/pkg/backends/options"
"github.com/trickstercache/trickster/v2/pkg/router"
"github.com/trickstercache/trickster/v2/pkg/router/lm"
)

func TestNewTimeseriesBackend(t *testing.T) {
tb, _ := NewTimeseriesBackend("test1", bo.New(), nil, router.NewRouter(), nil, nil)
tb, _ := NewTimeseriesBackend("test1", bo.New(), nil, lm.NewRouter(), nil, nil)
if tb.Name() != "test1" {
t.Error("expected test1 got", tb.Name())
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/config/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const (
// DefaultHealthHandlerPath defines the default path for the Health Handler
DefaultHealthHandlerPath = "/trickster/health"
// DefaultPurgeKeyHandlerPath defines the default path for the Cache Purge (by Key) Handler
DefaultPurgeKeyHandlerPath = "/trickster/purge/key/{backend}/{key}"
DefaultPurgeKeyHandlerPath = "/trickster/purge/key/"
// DefaultPurgePathHandlerPath defines the default path for the Cache Purge (by Path) Handler
// Requires ?backend={backend}&path={path}
DefaultPurgePathHandlerPath = "/trickster/purge/path"
Expand Down
24 changes: 17 additions & 7 deletions pkg/httpserver/httpserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import (
"github.com/trickstercache/trickster/v2/pkg/observability/metrics"
tr "github.com/trickstercache/trickster/v2/pkg/observability/tracing/registration"
"github.com/trickstercache/trickster/v2/pkg/proxy/handlers"
"github.com/trickstercache/trickster/v2/pkg/router"
"github.com/trickstercache/trickster/v2/pkg/router/lm"
"github.com/trickstercache/trickster/v2/pkg/routing"
)

Expand Down Expand Up @@ -130,10 +130,14 @@ func applyConfig(conf, oldConf *config.Config, wg *sync.WaitGroup, logger *tl.Lo
}

// every config (re)load is a new router
r := router.NewRouter()
mr := http.NewServeMux()
r := lm.NewRouter()
mr := lm.NewRouter()
mr.SetMatchingScheme(0)

r.RegisterRoute(conf.Main.PingHandlerPath, nil,
[]string{http.MethodGet, http.MethodHead}, false,
http.HandlerFunc((handlers.PingHandleFunc(conf))))

r.HandleFunc(conf.Main.PingHandlerPath, handlers.PingHandleFunc(conf)).Methods(http.MethodGet)
var caches = applyCachingConfig(conf, oldConf, logger, oldCaches)
rh := handlers.ReloadHandleFunc(Serve, conf, wg, logger, caches, args)

Expand All @@ -144,7 +148,12 @@ func applyConfig(conf, oldConf *config.Config, wg *sync.WaitGroup, logger *tl.Lo
return err
}

r.HandleFunc(conf.Main.PurgeKeyHandlerPath, handlers.PurgeKeyHandleFunc(conf, o)).Methods(http.MethodDelete)
if !strings.HasSuffix(conf.Main.PurgeKeyHandlerPath, "/") {
conf.Main.PurgeKeyHandlerPath += "/"
}
r.RegisterRoute(conf.Main.PurgeKeyHandlerPath, nil,
[]string{http.MethodDelete}, true,
http.HandlerFunc(handlers.PurgeKeyHandleFunc(conf, o)))

if hc != nil {
hc.Shutdown()
Expand Down Expand Up @@ -320,8 +329,9 @@ func validateConfig(conf *config.Config) error {
caches[k] = nil
}

r := router.NewRouter()
mr := http.NewServeMux()
r := lm.NewRouter()
mr := lm.NewRouter()
mr.SetMatchingScheme(0)
logger := tl.ConsoleLogger(conf.Logging.LogLevel)

tracers, err := tr.RegisterAll(conf, logger, true)
Expand Down
38 changes: 26 additions & 12 deletions pkg/httpserver/listeners.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ import (
"github.com/trickstercache/trickster/v2/pkg/proxy/handlers"
"github.com/trickstercache/trickster/v2/pkg/proxy/listener"
ttls "github.com/trickstercache/trickster/v2/pkg/proxy/tls"
"github.com/trickstercache/trickster/v2/pkg/router"
"github.com/trickstercache/trickster/v2/pkg/router/lm"
"github.com/trickstercache/trickster/v2/pkg/routing"
)

var lg = listener.NewListenerGroup()

func applyListenerConfigs(conf, oldConf *config.Config,
router, reloadHandler http.Handler, metricsRouter *http.ServeMux,
router, reloadHandler http.Handler, metricsRouter router.Router,
log *tl.Logger, tracers tracing.Tracers, o backends.Backends,
wg *sync.WaitGroup, errorFunc func()) {

Expand Down Expand Up @@ -137,8 +139,10 @@ func applyListenerConfigs(conf, oldConf *config.Config,
(!hasOldMC || (conf.Metrics.ListenAddress != oldConf.Metrics.ListenAddress ||
conf.Metrics.ListenPort != oldConf.Metrics.ListenPort)) {
lg.DrainAndClose("metricsListener", 0)
metricsRouter.Handle("/metrics", metrics.Handler())
metricsRouter.HandleFunc(conf.Main.ConfigHandlerPath, handlers.ConfigHandleFunc(conf))
metricsRouter.RegisterRoute("/metrics", []string{""},
[]string{http.MethodGet}, false, metrics.Handler())
metricsRouter.RegisterRoute(conf.Main.ConfigHandlerPath, []string{""},
[]string{http.MethodGet}, false, http.HandlerFunc(handlers.ConfigHandleFunc(conf)))
if conf.Main.PprofServer == "both" || conf.Main.PprofServer == "metrics" {
routing.RegisterPprofRoutes("metrics", metricsRouter, log)
}
Expand All @@ -147,32 +151,42 @@ func applyListenerConfigs(conf, oldConf *config.Config,
conf.Metrics.ListenAddress, conf.Metrics.ListenPort,
conf.Frontend.ConnectionsLimit, nil, metricsRouter, wg, nil, errorFunc, 0, log)
} else {
metricsRouter.Handle("/metrics", metrics.Handler())
metricsRouter.HandleFunc(conf.Main.ConfigHandlerPath, handlers.ConfigHandleFunc(conf))
metricsRouter.RegisterRoute("/metrics", []string{""},
[]string{http.MethodGet}, false, metrics.Handler())
metricsRouter.RegisterRoute(conf.Main.ConfigHandlerPath, []string{""},
[]string{http.MethodGet}, false, http.HandlerFunc(handlers.ConfigHandleFunc(conf)))
lg.UpdateRouter("metricsListener", metricsRouter)
}

rr := http.NewServeMux() // serveMux router for the Reload port
rr := lm.NewRouter() // serveMux router for the Reload port

// if the Reload HTTP port is configured, then set up the http listener instance
if conf.ReloadConfig != nil && conf.ReloadConfig.ListenPort > 0 &&
(!hasOldRC || (conf.ReloadConfig.ListenAddress != oldConf.ReloadConfig.ListenAddress ||
conf.ReloadConfig.ListenPort != oldConf.ReloadConfig.ListenPort)) {
wg.Add(1)
lg.DrainAndClose("reloadListener", time.Millisecond*500)
rr.HandleFunc(conf.Main.ConfigHandlerPath, handlers.ConfigHandleFunc(conf))
rr.Handle(conf.ReloadConfig.HandlerPath, reloadHandler)
rr.HandleFunc(conf.Main.PurgePathHandlerPath, handlers.PurgePathHandlerFunc(conf, &o))

rr.RegisterRoute(conf.Main.ConfigHandlerPath, []string{""},
[]string{http.MethodGet}, false, http.HandlerFunc(handlers.ConfigHandleFunc(conf)))
rr.RegisterRoute(conf.ReloadConfig.HandlerPath, []string{""},
[]string{http.MethodGet}, false, reloadHandler)
rr.RegisterRoute(conf.Main.PurgePathHandlerPath, []string{""},
[]string{http.MethodGet}, false, http.HandlerFunc(handlers.PurgePathHandlerFunc(conf, &o)))
if conf.Main.PprofServer == "both" || conf.Main.PprofServer == "reload" {
routing.RegisterPprofRoutes("reload", rr, log)
}
go lg.StartListener("reloadListener",
conf.ReloadConfig.ListenAddress, conf.ReloadConfig.ListenPort,
conf.Frontend.ConnectionsLimit, nil, rr, wg, nil, errorFunc, 0, log)
} else {
rr.HandleFunc(conf.Main.ConfigHandlerPath, handlers.ConfigHandleFunc(conf))
rr.Handle(conf.ReloadConfig.HandlerPath, reloadHandler)
rr.HandleFunc(conf.Main.PurgePathHandlerPath, handlers.PurgePathHandlerFunc(conf, &o))

rr.RegisterRoute(conf.Main.ConfigHandlerPath, []string{""},
[]string{http.MethodGet}, false, http.HandlerFunc(handlers.ConfigHandleFunc(conf)))
rr.RegisterRoute(conf.ReloadConfig.HandlerPath, []string{""},
[]string{http.MethodGet}, false, reloadHandler)
rr.RegisterRoute(conf.Main.PurgePathHandlerPath, []string{""},
[]string{http.MethodGet}, false, http.HandlerFunc(handlers.PurgePathHandlerFunc(conf, &o)))
lg.UpdateRouter("reloadListener", rr)
}
}
6 changes: 3 additions & 3 deletions pkg/proxy/handlers/clickhouse/clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
bo "github.com/trickstercache/trickster/v2/pkg/backends/options"
co "github.com/trickstercache/trickster/v2/pkg/cache/options"
"github.com/trickstercache/trickster/v2/pkg/cache/registration"
"github.com/trickstercache/trickster/v2/pkg/router"
"github.com/trickstercache/trickster/v2/pkg/router/lm"
"github.com/trickstercache/trickster/v2/pkg/routing"
)

Expand Down Expand Up @@ -57,8 +57,8 @@ func NewAcceleratorWithOptions(baseURL string, o *bo.Options, c *co.Options) (ht
o.Scheme = u.Scheme
o.Host = u.Host
o.PathPrefix = u.Path
r := router.NewRouter()
cl, err := clickhouse.NewClient("default", o, router.NewRouter(), cache, nil, nil)
r := lm.NewRouter()
cl, err := clickhouse.NewClient("default", o, lm.NewRouter(), cache, nil, nil)
if err != nil {
return nil, err
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/proxy/handlers/influxdb/influxdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
bo "github.com/trickstercache/trickster/v2/pkg/backends/options"
co "github.com/trickstercache/trickster/v2/pkg/cache/options"
"github.com/trickstercache/trickster/v2/pkg/cache/registration"
"github.com/trickstercache/trickster/v2/pkg/router"
"github.com/trickstercache/trickster/v2/pkg/router/lm"
"github.com/trickstercache/trickster/v2/pkg/routing"
)

Expand Down Expand Up @@ -57,8 +57,8 @@ func NewAcceleratorWithOptions(baseURL string, o *bo.Options, c *co.Options) (ht
o.Scheme = u.Scheme
o.Host = u.Host
o.PathPrefix = u.Path
r := router.NewRouter()
cl, err := influxdb.NewClient("default", o, router.NewRouter(), cache, nil, nil)
r := lm.NewRouter()
cl, err := influxdb.NewClient("default", o, lm.NewRouter(), cache, nil, nil)
if err != nil {
return nil, err
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/proxy/handlers/prometheus/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
"github.com/trickstercache/trickster/v2/pkg/backends/prometheus"
co "github.com/trickstercache/trickster/v2/pkg/cache/options"
"github.com/trickstercache/trickster/v2/pkg/cache/registration"
"github.com/trickstercache/trickster/v2/pkg/router"
"github.com/trickstercache/trickster/v2/pkg/router/lm"
"github.com/trickstercache/trickster/v2/pkg/routing"
)

Expand Down Expand Up @@ -57,8 +57,8 @@ func NewAcceleratorWithOptions(baseURL string, o *bo.Options, c *co.Options) (ht
o.Scheme = u.Scheme
o.Host = u.Host
o.PathPrefix = u.Path
r := router.NewRouter()
cl, err := prometheus.NewClient("default", o, router.NewRouter(), cache, nil, nil)
r := lm.NewRouter()
cl, err := prometheus.NewClient("default", o, lm.NewRouter(), cache, nil, nil)
if err != nil {
return nil, err
}
Expand Down
12 changes: 9 additions & 3 deletions pkg/proxy/handlers/purge.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,27 @@ package handlers

import (
"net/http"
"strings"

"github.com/trickstercache/trickster/v2/pkg/backends"
"github.com/trickstercache/trickster/v2/pkg/checksum/md5"
"github.com/trickstercache/trickster/v2/pkg/config"
"github.com/trickstercache/trickster/v2/pkg/observability/logging"
"github.com/trickstercache/trickster/v2/pkg/proxy/headers"
"github.com/trickstercache/trickster/v2/pkg/proxy/request"
"github.com/trickstercache/trickster/v2/pkg/router"
)

// PurgeHandleFunc purges an object from a cache based on key.
func PurgeKeyHandleFunc(conf *config.Config, from backends.Backends) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
params := router.Vars(req)
purgeFrom, purgeKey := params["backend"], params["key"]
vals := strings.Replace(req.URL.Path, conf.Main.PurgeKeyHandlerPath, "", 1)
parts := strings.Split(vals, "/")
if len(parts) != 2 {
http.NotFound(w, req)
return
}
purgeFrom := parts[0]
purgeKey := parts[1]
fromBackend := from.Get(purgeFrom)
if fromBackend == nil {
w.Header().Set(headers.NameContentType, headers.ValueTextPlain)
Expand Down
4 changes: 2 additions & 2 deletions pkg/proxy/handlers/rpc/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
rpc "github.com/trickstercache/trickster/v2/pkg/backends/reverseproxycache"
co "github.com/trickstercache/trickster/v2/pkg/cache/options"
"github.com/trickstercache/trickster/v2/pkg/cache/registration"
"github.com/trickstercache/trickster/v2/pkg/router"
"github.com/trickstercache/trickster/v2/pkg/router/lm"
"github.com/trickstercache/trickster/v2/pkg/routing"
)

Expand Down Expand Up @@ -57,7 +57,7 @@ func NewWithOptions(baseURL string, o *bo.Options, c *co.Options) (http.Handler,
o.Scheme = u.Scheme
o.Host = u.Host
o.PathPrefix = u.Path
r := router.NewRouter()
r := lm.NewRouter()
cl, err := rpc.NewClient("default", o, r, cache, nil, nil)
if err != nil {
return nil, err
Expand Down
2 changes: 2 additions & 0 deletions pkg/proxy/headers/headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const (
ValueApplicationFlux = "application/vnd.flux"
// ValueChunked represents the HTTP Header Value of "chunked"
ValueChunked = "chunked"
// ValueClose represents the HTTP Header Value of "close"
ValueClose = "close"
// ValueMaxAge represents the HTTP Header Value of "max-age"
ValueMaxAge = "max-age"
// ValueMultipartFormData represents the HTTP Header Value of "multipart/form-data"
Expand Down
4 changes: 2 additions & 2 deletions pkg/proxy/listener/listener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import (
"github.com/trickstercache/trickster/v2/pkg/observability/tracing/exporters/stdout"
"github.com/trickstercache/trickster/v2/pkg/proxy/errors"
ph "github.com/trickstercache/trickster/v2/pkg/proxy/handlers"
"github.com/trickstercache/trickster/v2/pkg/router"
"github.com/trickstercache/trickster/v2/pkg/router/lm"
testutil "github.com/trickstercache/trickster/v2/pkg/testutil"
tlstest "github.com/trickstercache/trickster/v2/pkg/testutil/tls"
)
Expand Down Expand Up @@ -224,7 +224,7 @@ func TestListenerConnectionLimitWorks(t *testing.T) {
}

go func() {
http.Serve(l, router.NewRouter())
http.Serve(l, lm.NewRouter())
}()

if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/proxy/paths/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ func SetDefaults(
p.ReqRewriter = ri
}
if len(p.Methods) == 0 {
p.Methods = []string{http.MethodGet, http.MethodHead}
p.Methods = []string{http.MethodGet}
}
p.Custom = make([]string, 0)
for _, pm := range pathMembers {
Expand Down Expand Up @@ -248,7 +248,7 @@ func SetDefaults(
p.MatchType = matching.PathMatchTypeExact
p.MatchTypeName = p.MatchType.String()
}
paths[p.Path+"-"+strings.Join(p.Methods, "-")] = p
paths[p.Path] = p
}
return nil
}
Loading

0 comments on commit f184a81

Please sign in to comment.