// Copyright Epic Games, Inc. All Rights Reserved. using EpicGames.Redis; using Microsoft.Extensions.Diagnostics.HealthChecks; using StackExchange.Redis; namespace HordeServer.Server { /// /// Provides access to a Redis database /// public interface IRedisService : IHealthCheck { /// /// Flag for whether the connection is read-only /// bool ReadOnlyMode { get; } /// /// Connection pool /// public RedisConnectionPool ConnectionPool { get; } } /// /// Extension methods for /// public static class RedisServiceExtensions { /// /// Get the least-loaded Redis connection from the pool /// Don't store the returned object and try to resolve this as late as possible to ensure load is balanced. /// /// A Redis connection multiplexer public static IConnectionMultiplexer GetConnection(this IRedisService redisService) => redisService.ConnectionPool.GetConnection(); /// /// Get the least-loaded Redis database from the connection pool /// Don't store the returned object and try to resolve this as late as possible to ensure load is balanced. /// /// A Redis database public static IDatabase GetDatabase(this IRedisService redisService) => redisService.ConnectionPool.GetDatabase(); /// /// Publish a message to a channel /// /// The redis service instance /// Channel to post to /// Message to post to the channel /// Flags for the request public static Task PublishAsync(this IRedisService redisService, RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None) => redisService.GetDatabase().PublishAsync(channel, message, flags); /// /// Publish a message to a channel /// /// Type of elements sent over the channel /// The redis service instance /// Channel to post to /// Message to post to the channel /// Flags for the request public static Task PublishAsync(this IRedisService redisService, RedisChannel channel, T message, CommandFlags flags = CommandFlags.None) => redisService.GetDatabase().PublishAsync(channel, message, flags); /// public static Task SubscribeAsync(this IRedisService redisService, RedisChannel channel, Action callback) => SubscribeAsync(redisService, channel, (ch, x) => callback(x)); /// public static Task SubscribeAsync(this IRedisService redisService, RedisChannel channel, Action callback) => SubscribeAsync(redisService, channel, (ch, x) => callback(x)); /// /// Subscribe to notifications on a channel /// /// The redis service instance /// Channel to monitor /// Callback for new events /// Subscription object public static async Task SubscribeAsync(this IRedisService redisService, RedisChannel channel, Action callback) { IConnectionMultiplexer connection = redisService.GetConnection(); return await connection.SubscribeAsync(channel, callback); } /// /// Subscribe to notifications on a channel /// /// Type of elements sent over the channel /// The redis service instance /// Channel to monitor /// Callback for new events /// Subscription object public static async Task SubscribeAsync(this IRedisService redisService, RedisChannel channel, Action, T> callback) { IConnectionMultiplexer connection = redisService.GetConnection(); return await connection.SubscribeAsync(channel, callback); } } }