From 7c3cccf7153738c1af9da87acb1c7666fa70834b Mon Sep 17 00:00:00 2001 From: Eno Compton Date: Mon, 6 May 2024 14:27:09 -0600 Subject: [PATCH] feat: add support for a lazy refresh (#2184) When clients run the Proxy in environments where the CPU may be throttled, the background connection info refresh operation can fail to complete, causing connection errors. This commit introduces an option for a lazy refresh. Connection info is retrieved on an as needed-basis and cached based on the associated certificate's expiration. No background goroutine runs, unlike the default refresh ahead cache. Enable it like so: ./alloydb-auth-proxy --lazy-refresh A lazy refresh may result in increased latency (more requests will be subject to waiting for the refresh to complete), but gains in reliability. Fixes #625 --- cmd/root.go | 6 ++++++ cmd/root_test.go | 8 ++++++++ internal/proxy/proxy.go | 10 ++++++++++ 3 files changed, 24 insertions(+) diff --git a/cmd/root.go b/cmd/root.go index 3f71983c..b0c0f381 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -591,6 +591,12 @@ only. Uses the port specified by the http-port flag.`) localFlags.BoolVar(&c.conf.RunConnectionTest, "run-connection-test", false, `Runs a connection test against all specified instances. If an instance is unreachable, the Proxy exits with a failure status code.`) + localFlags.BoolVar(&c.conf.LazyRefresh, "lazy-refresh", false, + `Configure a lazy refresh where connection info is retrieved only if +the cached copy has expired. Use this setting in environments where the +CPU may be throttled and a background refresh cannot run reliably +(e.g., Cloud Run)`, + ) // Global and per instance flags localFlags.StringVarP(&c.conf.Addr, "address", "a", "127.0.0.1", diff --git a/cmd/root_test.go b/cmd/root_test.go index 774bb0d0..202862c7 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -470,6 +470,14 @@ func TestNewCommandArguments(t *testing.T) { Debug: true, }), }, + { + desc: "using the lazy refresh flag", + args: []string{"--lazy-refresh", + "projects/proj/locations/region/clusters/clust/instances/inst"}, + want: withDefaults(&proxy.Config{ + LazyRefresh: true, + }), + }, { desc: "using the admin port flag", args: []string{"--admin-port", "7777", diff --git a/internal/proxy/proxy.go b/internal/proxy/proxy.go index 0f272a53..f3bffffd 100644 --- a/internal/proxy/proxy.go +++ b/internal/proxy/proxy.go @@ -90,6 +90,12 @@ type Config struct { // PSC enables connections via the PSC endpoint for all instances. PSC bool + // LazyRefresh configures the Go Connector to retrieve connection info + // lazily and as-needed. Otherwise, no background refresh cycle runs. This + // setting is useful in environments where the CPU may be throttled outside + // of a request context, e.g., Cloud Run. + LazyRefresh bool + // Token is the Bearer token used for authorization. Token string @@ -326,6 +332,10 @@ func (c *Config) DialerOptions(l alloydb.Logger) ([]alloydbconn.Option, error) { opts = append(opts, alloydbconn.WithDebugLogger(l)) } + if c.LazyRefresh { + opts = append(opts, alloydbconn.WithLazyRefresh()) + } + return opts, nil }