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
425 425
426func (h *BaseAPIHandler) applyRequestInterceptorsBeforeAuth(ctx context.Context, handlerType, requestedModel, requestID string, req coreexecutor.Request, opts coreexecutor.Options, skipPluginID string) (coreexecutor.Request, coreexecutor.Options, *interfaces.ErrorMessage) {426func (h *BaseAPIHandler) applyRequestInterceptorsBeforeAuth(ctx context.Context, handlerType, requestedModel, requestID string, req coreexecutor.Request, opts coreexecutor.Options, skipPluginID string) (coreexecutor.Request, coreexecutor.Options, *interfaces.ErrorMessage) {
427 host := h.interceptorHost()427 host := h.interceptorHost()
428 if host == nil {428 if !requestInterceptorsEnabled(host) {
429 return req, opts, nil429 return req, opts, nil
430 }430 }
431 resp := interceptRequestBeforeAuth(ctx, host, pluginapi.RequestInterceptRequest{431 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
34 *handlerInterceptorTestHost34 *handlerInterceptorTestHost
35}35}
36 36
37type handlerInterceptorDisabledRequestTestHost struct {
38 *handlerInterceptorTestHost
39}
40
37func (h *handlerInterceptorNoStreamTestHost) HasStreamInterceptors() bool {41func (h *handlerInterceptorNoStreamTestHost) HasStreamInterceptors() bool {
38 return false42 return false
39}43}
40 44
45func (h *handlerInterceptorDisabledRequestTestHost) HasRequestInterceptors() bool {
46 return false
47}
48
41func (h *handlerInterceptorTestHost) InterceptRequestBeforeAuth(ctx context.Context, req pluginapi.RequestInterceptRequest) pluginapi.RequestInterceptResponse {49func (h *handlerInterceptorTestHost) InterceptRequestBeforeAuth(ctx context.Context, req pluginapi.RequestInterceptRequest) pluginapi.RequestInterceptResponse {
42 if h != nil && h.interceptRequestBeforeAuth != nil {50 if h != nil && h.interceptRequestBeforeAuth != nil {
43 return h.interceptRequestBeforeAuth(ctx, req)51 return h.interceptRequestBeforeAuth(ctx, req)
@@ -566,6 +574,80 @@ func TestHandlerRequestInterceptorRewritesExecutorRequest(t *testing.T) { · 522 unmodified lines
566 }574 }
567}575}
568 576
577func 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
608func 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
569func TestHandlerRequestInterceptorEmptyBodyKeepsOriginalPayload(t *testing.T) {651func TestHandlerRequestInterceptorEmptyBodyKeepsOriginalPayload(t *testing.T) {
570 model := "handler-interceptor-empty-body-model"652 model := "handler-interceptor-empty-body-model"
571 executor := &interceptorCaptureExecutor{}653 executor := &interceptorCaptureExecutor{}