Repository: envoyproxy/ai-gateway
Pull request #297 (2025-02-06 02:14:14)

extproc: eliminates context.Background in config loader
**Commit Message**

This eliminates context.Background in config loading 
code path.

**Related Issues/PRs (if applicable)**

This is a follow up on #296 


Patch:
diff --git a/internal/extproc/backendauth/auth.go b/internal/extproc/backendauth/auth.go
index 8dd4fbc..1ba62ba 100644
--- a/internal/extproc/backendauth/auth.go
+++ b/internal/extproc/backendauth/auth.go
@@ -18,9 +18,9 @@ type Handler interface {
 }
 
 // NewHandler returns a new implementation of [Handler] based on the configuration.
-func NewHandler(config *filterapi.BackendAuth) (Handler, error) {
+func NewHandler(ctx context.Context, config *filterapi.BackendAuth) (Handler, error) {
 	if config.AWSAuth != nil {
-		return newAWSHandler(config.AWSAuth)
+		return newAWSHandler(ctx, config.AWSAuth)
 	} else if config.APIKey != nil {
 		return newAPIKeyHandler(config.APIKey)
 	}
diff --git a/internal/extproc/backendauth/aws.go b/internal/extproc/backendauth/aws.go
index e01ecc6..0bf6aa7 100644
--- a/internal/extproc/backendauth/aws.go
+++ b/internal/extproc/backendauth/aws.go
@@ -27,7 +27,7 @@ type awsHandler struct {
 	region      string
 }
 
-func newAWSHandler(awsAuth *filterapi.AWSAuth) (Handler, error) {
+func newAWSHandler(ctx context.Context, awsAuth *filterapi.AWSAuth) (Handler, error) {
 	var credentials aws.Credentials
 	var region string
 
@@ -35,14 +35,14 @@ func newAWSHandler(awsAuth *filterapi.AWSAuth) (Handler, error) {
 		region = awsAuth.Region
 		if len(awsAuth.CredentialFileName) != 0 {
 			cfg, err := config.LoadDefaultConfig(
-				context.Background(),
+				ctx,
 				config.WithSharedCredentialsFiles([]string{awsAuth.CredentialFileName}),
 				config.WithRegion(awsAuth.Region),
 			)
 			if err != nil {
 				return nil, fmt.Errorf("cannot load from credentials file: %w", err)
 			}
-			credentials, err = cfg.Credentials.Retrieve(context.Background())
+			credentials, err = cfg.Credentials.Retrieve(ctx)
 			if err != nil {
 				return nil, fmt.Errorf("cannot retrieve AWS credentials: %w", err)
 			}
diff --git a/internal/extproc/server.go b/internal/extproc/server.go
index 533e341..c791d81 100644
--- a/internal/extproc/server.go
+++ b/internal/extproc/server.go
@@ -44,7 +44,7 @@ func NewServer[P ProcessorIface](logger *slog.Logger, newProcessor func(*process
 }
 
 // LoadConfig updates the configuration of the external processor.
-func (s *Server[P]) LoadConfig(config *filterapi.Config) error {
+func (s *Server[P]) LoadConfig(ctx context.Context, config *filterapi.Config) error {
 	bodyParser, err := router.NewRequestBodyParser(config.Schema)
 	if err != nil {
 		return fmt.Errorf("cannot create request body parser: %w", err)
@@ -66,7 +66,7 @@ func (s *Server[P]) LoadConfig(config *filterapi.Config) error {
 			}
 
 			if b.Auth != nil {
-				h, err := backendauth.NewHandler(b.Auth)
+				h, err := backendauth.NewHandler(ctx, b.Auth)
 				if err != nil {
 					return fmt.Errorf("cannot create backend auth handler: %w", err)
 				}
diff --git a/internal/extproc/watcher.go b/internal/extproc/watcher.go
index 70ffab5..871f884 100644
--- a/internal/extproc/watcher.go
+++ b/internal/extproc/watcher.go
@@ -12,9 +12,10 @@ import (
 )
 
 // ConfigReceiver is an interface that can receive *filterapi.Config updates.
+// This is mostly for decoupling and testing purposes.
 type ConfigReceiver interface {
 	// LoadConfig updates the configuration.
-	LoadConfig(config *filterapi.Config) error
+	LoadConfig(ctx context.Context, config *filterapi.Config) error
 }
 
 type configWatcher struct {
@@ -85,7 +86,7 @@ func (cw *configWatcher) loadConfig(ctx context.Context) error {
 	if err != nil {
 		return err
 	}
-	return cw.rcv.LoadConfig(cfg)
+	return cw.rcv.LoadConfig(ctx, cfg)
 }
 
 // getConfigString gets a string representation of the current config


Test patch:
diff --git a/filterapi/filterconfig_test.go b/filterapi/filterconfig_test.go
index 89913c9..411c698 100644
--- a/filterapi/filterconfig_test.go
+++ b/filterapi/filterconfig_test.go
@@ -1,6 +1,7 @@
 package filterapi_test
 
 import (
+	"context"
 	"log/slog"
 	"os"
 	"path"
@@ -22,7 +23,7 @@ func TestDefaultConfig(t *testing.T) {
 	err = yaml.Unmarshal([]byte(filterapi.DefaultConfig), &cfg)
 	require.NoError(t, err)
 
-	err = server.LoadConfig(&cfg)
+	err = server.LoadConfig(context.Background(), &cfg)
 	require.NoError(t, err)
 }
 
diff --git a/internal/extproc/backendauth/auth_test.go b/internal/extproc/backendauth/auth_test.go
index 90d0ab9..3e24dd9 100644
--- a/internal/extproc/backendauth/auth_test.go
+++ b/internal/extproc/backendauth/auth_test.go
@@ -1,6 +1,7 @@
 package backendauth
 
 import (
+	"context"
 	"os"
 	"testing"
 
@@ -40,7 +41,7 @@ aws_secret_access_key = test
 		},
 	} {
 		t.Run(tt.name, func(t *testing.T) {
-			_, err := NewHandler(tt.config)
+			_, err := NewHandler(context.Background(), tt.config)
 			require.NoError(t, err)
 		})
 	}
diff --git a/internal/extproc/backendauth/aws_test.go b/internal/extproc/backendauth/aws_test.go
index e0d922b..19d00c3 100644
--- a/internal/extproc/backendauth/aws_test.go
+++ b/internal/extproc/backendauth/aws_test.go
@@ -16,7 +16,7 @@ func TestNewAWSHandler(t *testing.T) {
 	t.Setenv("AWS_ACCESS_KEY_ID", "test")
 	t.Setenv("AWS_SECRET_ACCESS_KEY", "secret")
 
-	handler, err := newAWSHandler(&filterapi.AWSAuth{})
+	handler, err := newAWSHandler(context.Background(), &filterapi.AWSAuth{})
 	require.NoError(t, err)
 	require.NotNil(t, handler)
 }
@@ -36,7 +36,7 @@ func TestAWSHandler_Do(t *testing.T) {
 	require.NoError(t, err)
 	require.NoError(t, file.Sync())
 
-	credentialFileHandler, err := newAWSHandler(&filterapi.AWSAuth{
+	credentialFileHandler, err := newAWSHandler(context.Background(), &filterapi.AWSAuth{
 		CredentialFileName: awsCredentialFile,
 		Region:             "us-east-1",
 	})
diff --git a/internal/extproc/server_test.go b/internal/extproc/server_test.go
index 4d44ebf..2e64363 100644
--- a/internal/extproc/server_test.go
+++ b/internal/extproc/server_test.go
@@ -30,7 +30,7 @@ func requireNewServerWithMockProcessor(t *testing.T) *Server[*mockProcessor] {
 func TestServer_LoadConfig(t *testing.T) {
 	t.Run("invalid input schema", func(t *testing.T) {
 		s := requireNewServerWithMockProcessor(t)
-		err := s.LoadConfig(&filterapi.Config{
+		err := s.LoadConfig(context.Background(), &filterapi.Config{
 			Schema: filterapi.VersionedAPISchema{Name: "some-invalid-schema"},
 		})
 		require.Error(t, err)
@@ -73,7 +73,7 @@ func TestServer_LoadConfig(t *testing.T) {
 			},
 		}
 		s := requireNewServerWithMockProcessor(t)
-		err := s.LoadConfig(config)
+		err := s.LoadConfig(context.Background(), config)
 		require.NoError(t, err)
 
 		require.NotNil(t, s.config)
diff --git a/internal/extproc/watcher_test.go b/internal/extproc/watcher_test.go
index 3f383bf..be66ba5 100644
--- a/internal/extproc/watcher_test.go
+++ b/internal/extproc/watcher_test.go
@@ -22,7 +22,7 @@ type mockReceiver struct {
 }
 
 // LoadConfig implements ConfigReceiver.
-func (m *mockReceiver) LoadConfig(cfg *filterapi.Config) error {
+func (m *mockReceiver) LoadConfig(_ context.Context, cfg *filterapi.Config) error {
 	m.mux.Lock()
 	defer m.mux.Unlock()
 	m.cfg = cfg