Skip to content

Setting client lib name properly by wrapping multiplxer creation #420

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/NRedisStack/Auxiliary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ namespace NRedisStack;

public static class Auxiliary
{
private static string? _libraryName = $"NRedisStack(.NET_v{Environment.Version})";
private static string? _libraryName = $"NRedisStack-{GetNRedisStackVersion()}";
private static bool _setInfo = true;
public static void ResetInfoDefaults()
{
_setInfo = true;
_libraryName = $"NRedisStack(.NET_v{Environment.Version})";
_libraryName = $"NRedisStack-{GetNRedisStackVersion()}";
}
public static List<object> MergeArgs(RedisKey key, params RedisValue[] items)
{
Expand Down Expand Up @@ -126,4 +126,7 @@ public static string GetNRedisStackVersion()
Version version = typeof(Auxiliary).Assembly.GetName().Version!;
return $"{version.Major}.{version.Minor}.{version.Build}";
}

internal static string GetNRedisStackLibName() => _libraryName!;

}
14 changes: 11 additions & 3 deletions src/NRedisStack/CoreCommands/CoreCommandsAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,20 @@ public static class CoreCommandsAsync //: ICoreCommandsAsync
/// <remarks><seealso href="https://redis.io/commands/client-setinfo/"/></remarks>
public static async Task<bool> ClientSetInfoAsync(this IDatabaseAsync db, SetInfoAttr attr, string value)
{
var compareVersions = db.Multiplexer.GetServer(db.Multiplexer.GetEndPoints()[0]).Version.CompareTo(new Version(7, 1, 242));
if (compareVersions < 0) // the server does not support the CLIENT SETNAME command
IServer server = db.Multiplexer.GetServer(db.Multiplexer.GetEndPoints()[0]);
return await server.ClientSetInfoAsync(attr, value);
}

internal static async Task<bool> ClientSetInfoAsync(this IServer server, SetInfoAttr attr, string value)
{
var compareVersions = server.Version.CompareTo(new Version(7, 1, 242));
if (compareVersions < 0) // the server does not support the CLIENT SETINFO command
{
return false;
}
return (await db.ExecuteAsync(CoreCommandBuilder.ClientSetInfo(attr, value))).OKtoBoolean();
await server.Multiplexer.GetDatabase().ExecuteAsync(CoreCommandBuilder.ClientSetInfo(attr, value));
var cmd = CoreCommandBuilder.ClientSetInfo(attr, value);
return (await server.ExecuteAsync(cmd.Command, cmd.Args)).OKtoBoolean();
}

/// <summary>
Expand Down
2,410 changes: 2,410 additions & 0 deletions src/NRedisStack/DatabaseWrapper.cs

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions src/NRedisStack/IRedisDatabase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using StackExchange.Redis;

namespace NRedisStack;

/// <summary>
/// This class is EXPERIMENTAL!! and may change or removed in future releases.
/// Interface that provides access to Redis commands
/// including Search, JSON, TimeSeries, Bloom and more..
/// </summary>
public interface IRedisDatabase : IDatabase
{
/// <summary>
/// Gets a command set for interacting with the RedisBloom Bloom Filter module.
/// </summary>
/// <returns>Command set for Bloom Filter operations.</returns>
public BloomCommands BF();

/// <summary>
/// Gets a command set for interacting with the RedisBloom Count-Min Sketch module.
/// </summary>
/// <returns>Command set for Count-Min Sketch operations.</returns>
public CmsCommands CMS();

/// <summary>
/// Gets a command set for interacting with the RedisBloom Cuckoo Filter module.
/// </summary>
/// <returns>Command set for Cuckoo Filter operations.</returns>
public CuckooCommands CF();

/// <summary>
/// Gets a command set for interacting with the RedisJSON module.
/// </summary>
/// <returns>Command set for JSON operations.</returns>
public JsonCommands JSON();

/// <summary>
/// Gets a command set for interacting with the RediSearch module.
/// </summary>
/// <param name="searchDialect">The search dialect version to use. Defaults to 2.</param>
/// <returns>Command set for search operations.</returns>
public SearchCommands FT(int? searchDialect = 2);

/// <summary>
/// Gets a command set for interacting with the Redis t-digest module.
/// </summary>
/// <returns>Command set for t-digest operations.</returns>
public TdigestCommands TDIGEST();

/// <summary>
/// Gets a command set for interacting with the RedisTimeSeries module.
/// </summary>
/// <returns>Command set for time series operations.</returns>
public TimeSeriesCommands TS();

/// <summary>
/// Gets a command set for interacting with the RedisBloom TopK module.
/// </summary>
/// <returns>Command set for TopK operations.</returns>
public TopKCommands TOPK();
}
127 changes: 127 additions & 0 deletions src/NRedisStack/RedisClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
using StackExchange.Redis;

namespace NRedisStack;

/// <summary>
/// This class is EXPERIMENTAL!! and may change or removed in future releases.
/// Represents a Redis client that can connect to a Redis server
/// providing access to <see cref="IRedisDatabase"/> instances as well as the underlying multiplexer.
/// </summary>
public class RedisClient
{
private ConnectionMultiplexer _multiplexer;

private RedisClient(ConnectionMultiplexer multiplexer)
{
_multiplexer = multiplexer;
}

/// <summary>
/// Creates a new <see cref="RedisClient"/> instance.
/// </summary>
/// <param name="configuration">The string configuration to use for this client.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public static async Task<RedisClient> ConnectAsync(string configuration, TextWriter? log = null) =>
await ConnectAsync(ConfigurationOptions.Parse(configuration), log);

/// <summary>
/// Creates a new <see cref="RedisClient"/> instance.
/// </summary>
/// <param name="configuration">The string configuration to use for this client.</param>
/// <param name="configure">Action to further modify the parsed configuration options.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public static async Task<RedisClient> ConnectAsync(string configuration, Action<ConfigurationOptions> configure, TextWriter? log = null)
{
Action<ConfigurationOptions> config = (ConfigurationOptions config) =>
{
configure?.Invoke(config);
SetNames(config);
};
return new RedisClient(await ConnectionMultiplexer.ConnectAsync(configuration, configure, log));
}

/// <summary>
/// Creates a new <see cref="ConnectionMultiplexer"/> instance.
/// </summary>
/// <param name="configuration">The configuration options to use for this client.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param>
/// <remarks>Note: For Sentinel, do <b>not</b> specify a <see cref="ConfigurationOptions.CommandMap"/> - this is handled automatically.</remarks>
public static async Task<RedisClient> ConnectAsync(ConfigurationOptions configuration, TextWriter? log = null)
{
SetNames(configuration);
return new RedisClient(await ConnectionMultiplexer.ConnectAsync(configuration, log));
}

/// <summary>
/// Creates a new <see cref="RedisClient"/> instance.
/// </summary>
/// <param name="configuration">The string configuration to use for this client.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public static RedisClient Connect(string configuration, TextWriter? log = null) =>
Connect(ConfigurationOptions.Parse(configuration), log);

/// <summary>
/// Creates a new <see cref="RedisClient"/> instance.
/// </summary>
/// <param name="configuration">The string configuration to use for this client.</param>
/// <param name="configure">Action to further modify the parsed configuration options.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param>
public static RedisClient Connect(string configuration, Action<ConfigurationOptions> configure, TextWriter? log = null)
{
Action<ConfigurationOptions> config = (ConfigurationOptions config) =>
{
configure?.Invoke(config);
SetNames(config);
};
return new RedisClient(ConnectionMultiplexer.Connect(configuration, configure, log));
}

/// <summary>
/// Creates a new <see cref="RedisClient"/> instance.
/// </summary>
/// <param name="configuration">The configuration options to use for this client.</param>
/// <param name="log">The <see cref="TextWriter"/> to log to.</param>
/// <remarks>Note: For Sentinel, do <b>not</b> specify a <see cref="ConfigurationOptions.CommandMap"/> - this is handled automatically.</remarks>
public static RedisClient Connect(ConfigurationOptions configuration, TextWriter? log = null)
{
SetNames(configuration);
return new RedisClient(ConnectionMultiplexer.Connect(configuration, log));
}

/// <summary>
/// Gets a database instance.
/// </summary>
/// <param name="db">The ID to get a database for.</param>
/// <param name="asyncState">The async state to pass into the resulting <see cref="RedisDatabase"/>.</param>
/// <returns></returns>
public IRedisDatabase GetDatabase(int db = -1, object? asyncState = null)
{
var idatabase = _multiplexer.GetDatabase(db, asyncState);
return new RedisDatabase(idatabase);
}

/// <summary>
/// Gets the underlying <see cref="ConnectionMultiplexer"/> instance.
/// </summary>
/// <returns></returns>
public ConnectionMultiplexer GetMultiplexer()
{
return _multiplexer;
}

private static void SetNames(ConfigurationOptions config)
{
if (config.LibraryName == null)
{
config.LibraryName = Auxiliary.GetNRedisStackLibName();
}

if (config.ClientName == null)
{
config.ClientName = (Environment.MachineName ?? Environment.GetEnvironmentVariable("ComputerName") ?? "Unknown") + $"-NRedisStack(.NET_v{Environment.Version})";
}
}
}



25 changes: 25 additions & 0 deletions src/NRedisStack/RedisDatabase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using NRedisStack.RedisStackCommands;
using StackExchange.Redis;

namespace NRedisStack;

internal class RedisDatabase : DatabaseWrapper, IRedisDatabase
{
public RedisDatabase(IDatabase db) : base(db) { }

public BloomCommands BF() => new BloomCommands(_db);

public CuckooCommands CF() => new CuckooCommands(_db);

public CmsCommands CMS() => new CmsCommands(_db);

public TopKCommands TOPK() => new TopKCommands(_db);

public TdigestCommands TDIGEST() => new TdigestCommands(_db);

public SearchCommands FT(int? searchDialect = 2) => new SearchCommands(_db, searchDialect);

public JsonCommands JSON() => new JsonCommands(_db);

public TimeSeriesCommands TS() => new TimeSeriesCommands(_db);
}
Loading
Loading