Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,7 @@ func WithParams(p Params) *Proxy {
}

// applies filters to a request
func (p *Proxy) applyFiltersToRequest(f []*routing.RouteFilter, ctx *context) []*routing.RouteFilter {
func (p *Proxy) applyFiltersToRequest(f []*routing.RouteFilter, ctx *context, counter *int) []*routing.RouteFilter {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the var name be index instead of counter ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No because we count number of filters executed in the request path

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I approved the PR, if the suggestion doen't make sense, just ignore it :)

if len(f) == 0 {
return f
}
Expand All @@ -927,6 +927,7 @@ func (p *Proxy) applyFiltersToRequest(f []*routing.RouteFilter, ctx *context) []
ctx.request = ctx.request.WithContext(labelCtx)

fi.Request(ctx)
(*counter)++

ctx.request = ctx.request.WithContext(parentCtx)
pprof.SetGoroutineLabels(parentCtx)
Expand Down Expand Up @@ -1246,6 +1247,7 @@ func stack() []byte {

func (p *Proxy) do(ctx *context, parentSpan ot.Span) (err error) {
var requestElapsed, responseElapsed time.Duration
processedFiltersCounter := 0

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar to the above comment, shouldn't this be something like lastProcessedFilterIndex ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, same here and "last" would be misleading


requestStopWatch, responseStopWatch := newStopWatch(), newStopWatch()
requestStopWatch.Start()
Expand All @@ -1259,6 +1261,10 @@ func (p *Proxy) do(ctx *context, parentSpan ot.Span) (err error) {
perr := &proxyError{
err: fmt.Errorf("panic caused by: %v", r),
}

if processedFiltersCounter != 0 {
p.applyFiltersOnError(ctx, ctx.route.Filters[:processedFiltersCounter])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we have another panic in this call?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then we likely panic

}
p.makeErrorResponse(ctx, perr)
err = perr
}
Expand Down Expand Up @@ -1302,7 +1308,7 @@ func (p *Proxy) do(ctx *context, parentSpan ot.Span) (err error) {
ctx.applyRoute(route, params, p.flags.PreserveHost())

requestStopWatch.Stop()
processedFilters := p.applyFiltersToRequest(ctx.route.Filters, ctx)
processedFilters := p.applyFiltersToRequest(ctx.route.Filters, ctx, &processedFiltersCounter)
requestStopWatch.Start()

// not every of these branches could end up in a response to the client
Expand Down
52 changes: 48 additions & 4 deletions proxy/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,14 @@ import (
"github.com/zalando/skipper/eskip"
"github.com/zalando/skipper/filters"
"github.com/zalando/skipper/filters/builtin"
fscheduler "github.com/zalando/skipper/filters/scheduler"
"github.com/zalando/skipper/loadbalancer"
"github.com/zalando/skipper/logging"
"github.com/zalando/skipper/logging/loggingtest"
"github.com/zalando/skipper/metrics/metricstest"
"github.com/zalando/skipper/routing"
"github.com/zalando/skipper/routing/testdataclient"
"github.com/zalando/skipper/scheduler"

teePredicate "github.com/zalando/skipper/predicates/tee"
)
Expand Down Expand Up @@ -1028,27 +1031,58 @@ func TestFilterPanic(t *testing.T) {
})
defer s.Close()

metrics := &metricstest.MockMetrics{}
defer metrics.Close()
d := 50 * time.Millisecond
reg := scheduler.RegistryWith(scheduler.Options{
Metrics: metrics,
EnableRouteFIFOMetrics: true,
MetricsUpdateTimeout: d,
})
Comment thread
madumalt marked this conversation as resolved.
defer reg.Close()

fr := make(filters.Registry)
fr.Register(builtin.NewAppendRequestHeader())
fr.Register(builtin.NewAppendResponseHeader())
fr.Register(fscheduler.NewFifo())
fr.Register(new(nilFilterSpec))

doc := fmt.Sprintf(`test:
Path("/foo") ->
fifo(2000,20,"1s") ->
appendRequestHeader("X-Expected", "before") ->
appendResponseHeader("X-Expected", "before") ->
nilFilter() ->
appendRequestHeader("X-Expected", "after") ->
appendResponseHeader("X-Expected", "after") ->
"%s"`, s.URL)

tp, err := newTestProxyWithFilters(fr, doc, FlagsNone)
require.NoError(t, err)
defer tp.close()
dc, err := testdataclient.NewDoc(doc)
if err != nil {
t.Fatalf("Failed to create testdataclient: %v", err)
}
defer dc.Close()
ro := routing.Options{
SignalFirstLoad: true,
FilterRegistry: fr,
DataClients: []routing.DataClient{dc},
PostProcessors: []routing.PostProcessor{reg},
}
rt := routing.New(ro)
defer rt.Close()
<-rt.FirstLoad()

pr := WithParams(Params{
Flags: FlagsNone,
Metrics: metrics,
Routing: rt,
})
defer pr.Close()

r := httptest.NewRequest("GET", "/foo", nil)
w := httptest.NewRecorder()
tp.proxy.ServeHTTP(w, r)
now := time.Now()
pr.ServeHTTP(w, r)

assert.Equal(t, http.StatusInternalServerError, w.Code)
assert.Equal(t, int32(0), backendRequests, "expected no backend request")
Expand All @@ -1059,6 +1093,16 @@ func TestFilterPanic(t *testing.T) {
if err = testLog.WaitFor(msg, 100*time.Millisecond); err != nil {
t.Errorf("expected '%s' in logs", msg)
}

// wait for updateMetrics to happen
time.Sleep(d - time.Since(now))

// metrics should show that we cleaned up the active request
metrics.WithGauges(func(g map[string]float64) {
assert.Equal(t, float64(0), g["fifo.test.active"])
assert.Equal(t, float64(0), g["fifo.test.queued"])
})

}

func TestFilterPanicPrintStackRate(t *testing.T) {
Expand Down
Loading