diff --git a/sources/Valkey.Glide/ConnectionConfiguration.cs b/sources/Valkey.Glide/ConnectionConfiguration.cs index be27310..96cd19d 100644 --- a/sources/Valkey.Glide/ConnectionConfiguration.cs +++ b/sources/Valkey.Glide/ConnectionConfiguration.cs @@ -25,9 +25,24 @@ internal record ConnectionConfig public Protocol? Protocol; public string? ClientName; public bool LazyConnect; + public bool RefreshTopologyFromInitialNodes; internal FFI.ConnectionConfig ToFfi() => - new(Addresses, TlsMode, ClusterMode, (uint?)RequestTimeout?.TotalMilliseconds, (uint?)ConnectionTimeout?.TotalMilliseconds, ReadFrom, RetryStrategy, AuthenticationInfo, DatabaseId, Protocol, ClientName, LazyConnect); + new( + Addresses, + TlsMode, + ClusterMode, + (uint?)RequestTimeout?.TotalMilliseconds, + (uint?)ConnectionTimeout?.TotalMilliseconds, + ReadFrom, + RetryStrategy, + AuthenticationInfo, + DatabaseId, + Protocol, + ClientName, + LazyConnect, + RefreshTopologyFromInitialNodes + ); } /// @@ -640,6 +655,30 @@ public class ClusterClientConfigurationBuilder : ClientConfigurationBuilder public ClusterClientConfigurationBuilder() : base(true) { } + #region Refresh Topology + /// + /// Enables refreshing the cluster topology using only the initial nodes. + /// + /// When this option is enabled, all topology updates (both the periodic checks and on-demand + /// refreshes triggered by topology changes) will query only the initial nodes provided when + /// creating the client, rather than using the internal cluster view. + /// + /// If not set, defaults to false (uses internal cluster view for topology refresh). + /// + public bool RefreshTopologyFromInitialNodes + { + get => Config.RefreshTopologyFromInitialNodes; + set => Config.RefreshTopologyFromInitialNodes = value; + } + + /// + public ClusterClientConfigurationBuilder WithRefreshTopologyFromInitialNodes(bool refreshTopologyFromInitialNodes) + { + RefreshTopologyFromInitialNodes = refreshTopologyFromInitialNodes; + return this; + } + #endregion + /// /// Complete the configuration with given settings. /// diff --git a/sources/Valkey.Glide/Internals/FFI.structs.cs b/sources/Valkey.Glide/Internals/FFI.structs.cs index 9c1fee9..0f684cf 100644 --- a/sources/Valkey.Glide/Internals/FFI.structs.cs +++ b/sources/Valkey.Glide/Internals/FFI.structs.cs @@ -213,7 +213,8 @@ public ConnectionConfig( uint databaseId, ConnectionConfiguration.Protocol? protocol, string? clientName, - bool lazyConnect = false) + bool lazyConnect = false, + bool refreshTopologyFromInitialNodes = false) { _addresses = addresses; _request = new() @@ -237,6 +238,7 @@ public ConnectionConfig( Protocol = protocol ?? default, ClientName = clientName, LazyConnect = lazyConnect, + RefreshTopologyFromInitialNodes = refreshTopologyFromInitialNodes, }; } @@ -785,6 +787,8 @@ private struct ConnectionRequest public string? ClientName; [MarshalAs(UnmanagedType.U1)] public bool LazyConnect; + [MarshalAs(UnmanagedType.U1)] + public bool RefreshTopologyFromInitialNodes; // TODO more config params, see ffi.rs } diff --git a/tests/Valkey.Glide.UnitTests/ConnectionConfigurationTests.cs b/tests/Valkey.Glide.UnitTests/ConnectionConfigurationTests.cs index bbcb04c..30514ac 100644 --- a/tests/Valkey.Glide.UnitTests/ConnectionConfigurationTests.cs +++ b/tests/Valkey.Glide.UnitTests/ConnectionConfigurationTests.cs @@ -50,7 +50,7 @@ public void WithAuthentication_PasswordOnly() } [Fact] - public void WithAuthentication_UsernameIamAuthConfig_ConfiguresCorrectly() + public void WithAuthentication_UsernameIamAuthConfig() { var iamConfig = new IamAuthConfig(ClusterName, ServiceType.ElastiCache, Region, RefreshIntervalSeconds); var builder = new StandaloneClientConfigurationBuilder(); @@ -172,4 +172,30 @@ public void WithCredentials_MultipleCalls_LastWins() Assert.Equal(FFI.ServiceType.MemoryDB, iamCredentials.ServiceType); Assert.False(iamCredentials.HasRefreshIntervalSeconds); } + + [Fact] + public void RefreshTopologyFromInitialNodes_Default() + { + var builder = new ClusterClientConfigurationBuilder(); + var config = builder.Build(); + Assert.False(config.Request.RefreshTopologyFromInitialNodes); + } + + [Fact] + public void RefreshTopologyFromInitialNodes_True() + { + var builder = new ClusterClientConfigurationBuilder(); + builder.WithRefreshTopologyFromInitialNodes(true); + var config = builder.Build(); + Assert.True(config.Request.RefreshTopologyFromInitialNodes); + } + + [Fact] + public void RefreshTopologyFromInitialNodes_False() + { + var builder = new ClusterClientConfigurationBuilder(); + builder.WithRefreshTopologyFromInitialNodes(false); + var config = builder.Build(); + Assert.False(config.Request.RefreshTopologyFromInitialNodes); + } }