// 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);
}
}
}