History

Merge pull request #4360 from router-for-me/perf/skip-inactive-request-interceptors

Luis Pater committed 3 months ago

Commit 810d4dd2 parents 8b02fed 970529b2 files · +83 −1Browse files

Unified · Split

2 files
  1. sdk/api/handlers/handlers_interceptors.go +1 −1
  2. sdk/api/handlers/handlers_interceptors_test.go +82 −0
sdk/api/handlers/handlers_interceptors.go+1−1
@@ -425,7 +425,7 @@ func interceptStreamChunk(ctx context.Context, host PluginInterceptorHost, req p · 424 unmodified lines
425425
426426 func (h *BaseAPIHandler) applyRequestInterceptorsBeforeAuth(ctx context.Context, handlerType, requestedModel, requestID string, req coreexecutor.Request, opts coreexecutor.Options, skipPluginID string) (coreexecutor.Request, coreexecutor.Options, *interfaces.ErrorMessage) {
427427 host := h.interceptorHost()
428− if host == nil {
428+ if !requestInterceptorsEnabled(host) {
429429 return req, opts, nil
430430 }
431431 resp := interceptRequestBeforeAuth(ctx, host, pluginapi.RequestInterceptRequest{
sdk/api/handlers/handlers_interceptors_test.go+82−0
@@ -34,10 +34,18 @@ type handlerInterceptorNoStreamTestHost struct { · 33 unmodified lines
3434 *handlerInterceptorTestHost
3535 }
3636
37+type handlerInterceptorDisabledRequestTestHost struct {
38+ *handlerInterceptorTestHost
39+}
40+
3741 func (h *handlerInterceptorNoStreamTestHost) HasStreamInterceptors() bool {
3842 return false
3943 }
4044
45+func (h *handlerInterceptorDisabledRequestTestHost) HasRequestInterceptors() bool {
46+ return false
47+}
48+
4149 func (h *handlerInterceptorTestHost) InterceptRequestBeforeAuth(ctx context.Context, req pluginapi.RequestInterceptRequest) pluginapi.RequestInterceptResponse {
4250 if h != nil && h.interceptRequestBeforeAuth != nil {
4351 return h.interceptRequestBeforeAuth(ctx, req)
@@ -566,6 +574,80 @@ func TestHandlerRequestInterceptorRewritesExecutorRequest(t *testing.T) { · 522 unmodified lines
566574 }
567575 }
568576
577+func TestHandlerSkipsDisabledRequestInterceptorsWithoutCopyingPayload(t *testing.T) {
578+ payload := []byte(`{"model":"disabled-interceptor-model"}`)
579+ called := false
580+ handler := NewBaseAPIHandlers(&sdkconfig.SDKConfig{}, nil)
581+ handler.SetPluginHost(&handlerInterceptorDisabledRequestTestHost{
582+ handlerInterceptorTestHost: &handlerInterceptorTestHost{
583+ interceptRequestBeforeAuth: func(context.Context, pluginapi.RequestInterceptRequest) pluginapi.RequestInterceptResponse {
584+ called = true
585+ return pluginapi.RequestInterceptResponse{Body: []byte(`{"unexpected":true}`)}
586+ },
587+ },
588+ })
589+
590+ req := coreexecutor.Request{Model: "disabled-interceptor-model", Payload: payload}
591+ opts := coreexecutor.Options{OriginalRequest: payload}
592+ gotReq, gotOpts, err := handler.applyRequestInterceptorsBeforeAuth(context.Background(), "openai", req.Model, "test-req", req, opts, "")
593+ if err != nil {
594+ t.Fatalf("unexpected error: %v", err)
595+ }
596+
597+ if called {
598+ t.Fatal("disabled request interceptor was called")
599+ }
600+ if len(gotReq.Payload) != len(payload) || &gotReq.Payload[0] != &payload[0] {
601+ t.Fatal("request payload was copied")
602+ }
603+ if len(gotOpts.OriginalRequest) != len(payload) || &gotOpts.OriginalRequest[0] != &payload[0] {
604+ t.Fatal("original request was copied")
605+ }
606+}
607+
608+func BenchmarkHandlerRequestInterceptors(b *testing.B) {
609+ sizes := []struct {
610+ name string
611+ bytes int
612+ }{
613+ {name: "1KiB", bytes: 1 << 10},
614+ {name: "1MiB", bytes: 1 << 20},
615+ {name: "8MiB", bytes: 8 << 20},
616+ }
617+ hosts := []struct {
618+ name string
619+ host PluginInterceptorHost
620+ }{
621+ {
622+ name: "disabled",
623+ host: &handlerInterceptorDisabledRequestTestHost{
624+ handlerInterceptorTestHost: &handlerInterceptorTestHost{},
625+ },
626+ },
627+ {name: "active", host: &handlerInterceptorTestHost{}},
628+ }
629+
630+ for _, size := range sizes {
631+ payload := make([]byte, size.bytes)
632+ req := coreexecutor.Request{Model: "benchmark-model", Payload: payload}
633+ opts := coreexecutor.Options{OriginalRequest: payload}
634+ for _, host := range hosts {
635+ b.Run(host.name+"/"+size.name, func(b *testing.B) {
636+ handler := NewBaseAPIHandlers(&sdkconfig.SDKConfig{}, nil)
637+ handler.SetPluginHost(host.host)
638+ b.ReportAllocs()
639+ b.ResetTimer()
640+ for range b.N {
641+ gotReq, gotOpts, _ := handler.applyRequestInterceptorsBeforeAuth(context.Background(), "openai", req.Model, "benchmark-req", req, opts, "")
642+ if len(gotReq.Payload) != size.bytes || len(gotOpts.OriginalRequest) != size.bytes {
643+ b.Fatal("request payload length changed")
644+ }
645+ }
646+ })
647+ }
648+ }
649+}
650+
569651 func TestHandlerRequestInterceptorEmptyBodyKeepsOriginalPayload(t *testing.T) {
570652 model := "handler-interceptor-empty-body-model"
571653 executor := &interceptorCaptureExecutor{}