Skip to content

Commit

Permalink
DefaultOptionsProvider: allow overriding LibName (#2453)
Browse files Browse the repository at this point in the history
If a wrapper package is generally in use in a deployment, it may want to override what we set as the library name in `CLIENT SETINFO lib-name <name>`. This allows doing so via the `DefaultOptionsProvider` (intentionally not on `ConfigurationOptions` directly as version isn't either).

Note that this does NOT upgrade the test suite to 7.2.0 RC1. I did test and this works, but there are other breaks we need to evaluate - I'll open another PR separately to demonstrate.
  • Loading branch information
NickCraver committed May 2, 2023
1 parent 9fda7c5 commit 0dfa58f
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 7 deletions.
1 change: 1 addition & 0 deletions docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Current package versions:
- Fix [#2449](https://github.com/StackExchange/StackExchange.Redis/issues/2449): Resolve AOT trim warnings in `TryGetAzureRoleInstanceIdNoThrow` ([#2451 by eerhardt](https://github.com/StackExchange/StackExchange.Redis/pull/2451))
- Adds: Support for `HTTP/1.1 200 Connection established` in HTTP Tunnel ([#2448 by flobernd](https://github.com/StackExchange/StackExchange.Redis/pull/2448))
- Adds: Timeout duration to backlog timeout error messages ([#2452 by NickCraver](https://github.com/StackExchange/StackExchange.Redis/pull/2452))
- Adds: `DefaultOptionsProvider.LibraryName` for specifying lib-name passed to `CLIENT SETINFO` in Redis 7.2+ ([#2453 by NickCraver](https://github.com/StackExchange/StackExchange.Redis/pull/2453))

## 2.6.104

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@ public static void AddProvider(DefaultOptionsProvider provider)
?? ComputerName
?? "StackExchange.Redis") + "(SE.Redis-v" + LibraryVersion + ")";

/// <summary>
/// Gets the library name to use for CLIENT SETINFO lib-name calls to Redis during handshake.
/// Defaults to "SE.Redis".
/// </summary>
public virtual string LibraryName => "SE.Redis";

/// <summary>
/// String version of the StackExchange.Redis library, for use in any options.
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1788,6 +1788,7 @@ virtual StackExchange.Redis.Configuration.DefaultOptionsProvider.IncludeDetailIn
virtual StackExchange.Redis.Configuration.DefaultOptionsProvider.IncludePerformanceCountersInExceptions.get -> bool
virtual StackExchange.Redis.Configuration.DefaultOptionsProvider.IsMatch(System.Net.EndPoint! endpoint) -> bool
virtual StackExchange.Redis.Configuration.DefaultOptionsProvider.KeepAliveInterval.get -> System.TimeSpan
virtual StackExchange.Redis.Configuration.DefaultOptionsProvider.LibraryName.get -> string!
virtual StackExchange.Redis.Configuration.DefaultOptionsProvider.Password.get -> string?
virtual StackExchange.Redis.Configuration.DefaultOptionsProvider.Proxy.get -> StackExchange.Redis.Proxy
virtual StackExchange.Redis.Configuration.DefaultOptionsProvider.ReconnectRetryPolicy.get -> StackExchange.Redis.IReconnectRetryPolicy?
Expand Down
3 changes: 2 additions & 1 deletion src/StackExchange.Redis/RedisFeatures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ namespace StackExchange.Redis
v6_0_0 = new Version(6, 0, 0),
v6_0_6 = new Version(6, 0, 6),
v6_2_0 = new Version(6, 2, 0),
v7_0_0_rc1 = new Version(6, 9, 240); // 7.0 RC1 is version 6.9.240
v7_0_0_rc1 = new Version(6, 9, 240), // 7.0 RC1 is version 6.9.240
v7_2_0_rc1 = new Version(7, 1, 240); // 7.2 RC1 is version 7.1.240

private readonly Version version;

Expand Down
1 change: 0 additions & 1 deletion src/StackExchange.Redis/RedisLiterals.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ public static readonly RedisValue
REWRITE = "REWRITE",
RIGHT = "RIGHT",
SAVE = "SAVE",
SE_Redis = "SE.Redis",
SEGFAULT = "SEGFAULT",
SET = "SET",
SETINFO = "SETINFO",
Expand Down
12 changes: 8 additions & 4 deletions src/StackExchange.Redis/ServerEndPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -935,10 +935,14 @@ private async Task HandshakeAsync(PhysicalConnection connection, LogProxy? log)
// server version, so we will use this speculatively and hope for the best
log?.WriteLine($"{Format.ToString(this)}: Setting client lib/ver");

msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.CLIENT,
RedisLiterals.SETINFO, RedisLiterals.lib_name, RedisLiterals.SE_Redis);
msg.SetInternalCall();
await WriteDirectOrQueueFireAndForgetAsync(connection, msg, ResultProcessor.DemandOK).ForAwait();
var libName = Multiplexer.RawConfig.Defaults.LibraryName;
if (!string.IsNullOrWhiteSpace(libName))
{
msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.CLIENT,
RedisLiterals.SETINFO, RedisLiterals.lib_name, libName);
msg.SetInternalCall();
await WriteDirectOrQueueFireAndForgetAsync(connection, msg, ResultProcessor.DemandOK).ForAwait();
}

var version = Utils.GetLibVersion();
if (!string.IsNullOrWhiteSpace(version))
Expand Down
29 changes: 29 additions & 0 deletions tests/StackExchange.Redis.Tests/DefaultOptionsTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -158,4 +159,32 @@ public async Task ClientNameExplicitWins()
Assert.True(conn.IsConnected);
Assert.Equal("FooBar", conn.ClientName);
}

public class TestLibraryNameOptionsProvider : DefaultOptionsProvider
{
public string Id { get; } = Guid.NewGuid().ToString();
public override string LibraryName => Id;
}

[Fact]
public async Task LibraryNameOverride()
{
var options = ConfigurationOptions.Parse(GetConfiguration());
var defaults = new TestLibraryNameOptionsProvider();
options.AllowAdmin = true;
options.Defaults = defaults;

using var conn = await ConnectionMultiplexer.ConnectAsync(options, Writer);
// CLIENT SETINFO is in 7.2.0+
ThrowIfBelowMinVersion(conn, RedisFeatures.v7_2_0_rc1);

var clients = await GetServer(conn).ClientListAsync();
foreach (var client in clients)
{
Log("Library name: " + client.LibraryName);
}

Assert.True(conn.IsConnected);
Assert.True(clients.Any(c => c.LibraryName == defaults.LibraryName), "Did not find client with name: " + defaults.Id);
}
}
2 changes: 1 addition & 1 deletion tests/StackExchange.Redis.Tests/TestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ protected static IServer GetAnyPrimary(IConnectionMultiplexer muxer)
return conn;
}

private void ThrowIfBelowMinVersion(IInternalConnectionMultiplexer conn, Version? requiredVersion)
protected void ThrowIfBelowMinVersion(IConnectionMultiplexer conn, Version? requiredVersion)
{
if (requiredVersion is null)
{
Expand Down

0 comments on commit 0dfa58f

Please sign in to comment.