Skip to content

Commit ce9506b

Browse files
mgravellNickCraver
andauthored
add LibraryName at ConfigurationOptions level (#2502)
* add LibraryName at ConfigurationOptions level * add PR number * add GetProvider * remove `libname` config-string; move docs to code-only section * remove s_DefaultProvider * Update docs/ReleaseNotes.md --------- Co-authored-by: Nick Craver <nrcraver@gmail.com>
1 parent cd2dbb4 commit ce9506b

File tree

8 files changed

+54
-15
lines changed

8 files changed

+54
-15
lines changed

docs/Configuration.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ The `ConfigurationOptions` object has a wide range of properties, all of which a
9797
| tiebreaker={string} | `TieBreaker` | `__Booksleeve_TieBreak` | Key to use for selecting a server in an ambiguous primary scenario |
9898
| version={string} | `DefaultVersion` | (`4.0` in Azure, else `2.0`) | Redis version level (useful when the server does not make this available) |
9999
| tunnel={string} | `Tunnel` | `null` | Tunnel for connections (use `http:{proxy url}` for "connect"-based proxy server) |
100-
| setlib={bool} | `SetClientLibrary` | `true` | Whether to attempt to use `CLIENT SETINFO` to set the lib name/version on the connection |
100+
| setlib={bool} | `SetClientLibrary` | `true` | Whether to attempt to use `CLIENT SETINFO` to set the library name/version on the connection |
101101

102102
Additional code-only options:
103103
- ReconnectRetryPolicy (`IReconnectRetryPolicy`) - Default: `ReconnectRetryPolicy = ExponentialRetry(ConnectTimeout / 2);`
@@ -115,6 +115,8 @@ Additional code-only options:
115115
- HeartbeatInterval - Default: `1000ms`
116116
- Allows running the heartbeat more often which importantly includes timeout evaluation for async commands. For example if you have a 50ms async command timeout, we're only actually checking it during the heartbeat (once per second by default), so it's possible 50-1050ms pass _before we notice it timed out_. If you want more fidelity in that check and to observe that a server failed faster, you can lower this to run the heartbeat more often to achieve that.
117117
- **Note: heartbeats are not free and that's why the default is 1 second. There is additional overhead to running this more often simply because it does some work each time it fires.**
118+
- LibraryName - Default: `SE.Redis` (unless a `DefaultOptionsProvider` specifies otherwise)
119+
- The library name to use with `CLIENT SETINFO` when setting the library name/version on the connection
118120

119121
Tokens in the configuration string are comma-separated; any without an `=` sign are assumed to be redis server endpoints. Endpoints without an explicit port will use 6379 if ssl is not enabled, and 6380 if ssl is enabled.
120122
Tokens starting with `$` are taken to represent command maps, for example: `$config=cfg`.

docs/ReleaseNotes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Current package versions:
1111
- Change: Target net6.0 instead of net5.0, since net5.0 is end of life. ([#2497 by eerhardt](https://github.com/StackExchange/StackExchange.Redis/pull/2497))
1212
- Fix: Fix nullability annotation of IConnectionMultiplexer.RegisterProfiler ([#2494 by eerhardt](https://github.com/StackExchange/StackExchange.Redis/pull/2494))
1313
- Add: `Timer.ActiveCount` under `POOL` in timeout messages on .NET 6+ to help diagnose timer overload affecting timeout evaluations ([#2500 by NickCraver](https://github.com/StackExchange/StackExchange.Redis/pull/2500))
14+
- Add: `LibraryName` configuration option; allows the library name to be controlled at the individual options level (in addition to the existing controls in `DefaultOptionsProvider`) ([#2502 by mgravell](https://github.com/StackExchange/StackExchange.Redis/pull/2502))
15+
- Add: `DefaultOptionsProvider.GetProvider` allows lookup of provider by endpoint ([#2502 by mgravell](https://github.com/StackExchange/StackExchange.Redis/pull/2502))
1416

1517
## 2.6.116
1618

src/StackExchange.Redis/Configuration/AzureOptionsProvider.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
using System;
2-
using System.Collections.Generic;
1+
using StackExchange.Redis.Maintenance;
2+
using System;
33
using System.Net;
44
using System.Threading.Tasks;
5-
using StackExchange.Redis.Maintenance;
65

76
namespace StackExchange.Redis.Configuration
87
{

src/StackExchange.Redis/Configuration/DefaultOptionsProvider.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public static void AddProvider(DefaultOptionsProvider provider)
5252
/// <summary>
5353
/// Gets a provider for the given endpoints, falling back to <see cref="DefaultOptionsProvider"/> if nothing more specific is found.
5454
/// </summary>
55-
internal static Func<EndPointCollection, DefaultOptionsProvider> GetForEndpoints { get; } = (endpoints) =>
55+
public static DefaultOptionsProvider GetProvider(EndPointCollection endpoints)
5656
{
5757
foreach (var provider in KnownProviders)
5858
{
@@ -65,8 +65,23 @@ public static void AddProvider(DefaultOptionsProvider provider)
6565
}
6666
}
6767

68-
return new DefaultOptionsProvider();
69-
};
68+
return new DefaultOptionsProvider(); // no memoize; allow mutability concerns (also impacts subclasses, but: pragmatism)
69+
}
70+
71+
/// <summary>
72+
/// Gets a provider for a given endpoints, falling back to <see cref="DefaultOptionsProvider"/> if nothing more specific is found.
73+
/// </summary>
74+
public static DefaultOptionsProvider GetProvider(EndPoint endpoint)
75+
{
76+
foreach (var provider in KnownProviders)
77+
{
78+
if (provider.IsMatch(endpoint))
79+
{
80+
return provider;
81+
}
82+
}
83+
return new DefaultOptionsProvider(); // no memoize; allow mutability concerns (also impacts subclasses, but: pragmatism)
84+
}
7085

7186
/// <summary>
7287
/// Gets or sets whether connect/configuration timeouts should be explicitly notified via a TimeoutException.

src/StackExchange.Redis/ConfigurationOptions.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ public static string TryNormalize(string value)
180180
/// </summary>
181181
public DefaultOptionsProvider Defaults
182182
{
183-
get => defaultOptions ??= DefaultOptionsProvider.GetForEndpoints(EndPoints);
183+
get => defaultOptions ??= DefaultOptionsProvider.GetProvider(EndPoints);
184184
set => defaultOptions = value;
185185
}
186186

@@ -233,14 +233,23 @@ public bool UseSsl
233233
}
234234

235235
/// <summary>
236-
/// Gets or sets whether the library should identify itself by library-name/version when possible
236+
/// Gets or sets whether the library should identify itself by library-name/version when possible.
237237
/// </summary>
238238
public bool SetClientLibrary
239239
{
240240
get => setClientLibrary ?? Defaults.SetClientLibrary;
241241
set => setClientLibrary = value;
242242
}
243243

244+
245+
/// <summary>
246+
/// Gets or sets the library name to use for CLIENT SETINFO lib-name calls to Redis during handshake.
247+
/// Defaults to "SE.Redis".
248+
/// </summary>
249+
/// <remarks>If the value is null, empty or whitespace, then the value from the options-provideer is used;
250+
/// to disable the library name feature, use <see cref="SetClientLibrary"/> instead.</remarks>
251+
public string? LibraryName { get; set; }
252+
244253
/// <summary>
245254
/// Automatically encodes and decodes channels.
246255
/// </summary>
@@ -671,6 +680,7 @@ public static ConfigurationOptions Parse(string configuration, bool ignoreUnknow
671680
#endif
672681
Tunnel = Tunnel,
673682
setClientLibrary = setClientLibrary,
683+
LibraryName = LibraryName,
674684
};
675685

676686
/// <summary>

src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ StackExchange.Redis.ConfigurationOptions.IncludePerformanceCountersInExceptions.
243243
StackExchange.Redis.ConfigurationOptions.IncludePerformanceCountersInExceptions.set -> void
244244
StackExchange.Redis.ConfigurationOptions.KeepAlive.get -> int
245245
StackExchange.Redis.ConfigurationOptions.KeepAlive.set -> void
246+
StackExchange.Redis.ConfigurationOptions.LibraryName.get -> string?
247+
StackExchange.Redis.ConfigurationOptions.LibraryName.set -> void
246248
StackExchange.Redis.ConfigurationOptions.Password.get -> string?
247249
StackExchange.Redis.ConfigurationOptions.Password.set -> void
248250
StackExchange.Redis.ConfigurationOptions.PreserveAsyncOrder.get -> bool
@@ -1604,6 +1606,8 @@ static StackExchange.Redis.Condition.StringLengthLessThan(StackExchange.Redis.Re
16041606
static StackExchange.Redis.Condition.StringNotEqual(StackExchange.Redis.RedisKey key, StackExchange.Redis.RedisValue value) -> StackExchange.Redis.Condition!
16051607
static StackExchange.Redis.Configuration.DefaultOptionsProvider.AddProvider(StackExchange.Redis.Configuration.DefaultOptionsProvider! provider) -> void
16061608
static StackExchange.Redis.Configuration.DefaultOptionsProvider.ComputerName.get -> string!
1609+
static StackExchange.Redis.Configuration.DefaultOptionsProvider.GetProvider(StackExchange.Redis.EndPointCollection! endpoints) -> StackExchange.Redis.Configuration.DefaultOptionsProvider!
1610+
static StackExchange.Redis.Configuration.DefaultOptionsProvider.GetProvider(System.Net.EndPoint! endpoint) -> StackExchange.Redis.Configuration.DefaultOptionsProvider!
16071611
static StackExchange.Redis.Configuration.DefaultOptionsProvider.LibraryVersion.get -> string!
16081612
static StackExchange.Redis.ConfigurationOptions.Parse(string! configuration) -> StackExchange.Redis.ConfigurationOptions!
16091613
static StackExchange.Redis.ConfigurationOptions.Parse(string! configuration, bool ignoreUnknown) -> StackExchange.Redis.ConfigurationOptions!

src/StackExchange.Redis/ServerEndPoint.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -898,8 +898,9 @@ private async Task HandshakeAsync(PhysicalConnection connection, LogProxy? log)
898898
}
899899
Message msg;
900900
// Note that we need "" (not null) for password in the case of 'nopass' logins
901-
string? user = Multiplexer.RawConfig.User;
902-
string password = Multiplexer.RawConfig.Password ?? "";
901+
var config = Multiplexer.RawConfig;
902+
string? user = config.User;
903+
string password = config.Password ?? "";
903904
if (!string.IsNullOrWhiteSpace(user))
904905
{
905906
log?.WriteLine($"{Format.ToString(this)}: Authenticating (user/password)");
@@ -929,13 +930,19 @@ private async Task HandshakeAsync(PhysicalConnection connection, LogProxy? log)
929930
await WriteDirectOrQueueFireAndForgetAsync(connection, msg, ResultProcessor.DemandOK).ForAwait();
930931
}
931932
}
932-
if (Multiplexer.RawConfig.SetClientLibrary)
933+
if (config.SetClientLibrary)
933934
{
934935
// note that this is a relatively new feature, but usually we won't know the
935936
// server version, so we will use this speculatively and hope for the best
936937
log?.WriteLine($"{Format.ToString(this)}: Setting client lib/ver");
937938

938-
var libName = Multiplexer.RawConfig.Defaults.LibraryName;
939+
var libName = config.LibraryName;
940+
if (string.IsNullOrWhiteSpace(libName))
941+
{
942+
// defer to provider if missing (note re null vs blank; if caller wants to disable
943+
// it, they should set SetClientLibrary to false, not set the name to empty string)
944+
libName = config.Defaults.LibraryName;
945+
}
939946
if (!string.IsNullOrWhiteSpace(libName))
940947
{
941948
msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.CLIENT,

tests/StackExchange.Redis.Tests/DefaultOptionsTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ public void IsMatchOnDomain()
5252
DefaultOptionsProvider.AddProvider(new TestOptionsProvider(".testdomain"));
5353

5454
var epc = new EndPointCollection(new List<EndPoint>() { new DnsEndPoint("local.testdomain", 0) });
55-
var provider = DefaultOptionsProvider.GetForEndpoints(epc);
55+
var provider = DefaultOptionsProvider.GetProvider(epc);
5656
Assert.IsType<TestOptionsProvider>(provider);
5757

5858
epc = new EndPointCollection(new List<EndPoint>() { new DnsEndPoint("local.nottestdomain", 0) });
59-
provider = DefaultOptionsProvider.GetForEndpoints(epc);
59+
provider = DefaultOptionsProvider.GetProvider(epc);
6060
Assert.IsType<DefaultOptionsProvider>(provider);
6161
}
6262

0 commit comments

Comments
 (0)