-
Notifications
You must be signed in to change notification settings - Fork 0
/
HealthChecksRedisExtensions.cs
77 lines (68 loc) · 2.97 KB
/
HealthChecksRedisExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using StackExchange.Redis;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace NetPro.Checker
{
public static class HealthChecksRedisExtensions
{
private static readonly string NAME = "redis";
/// <summary>
/// Add a health check for Redis services.
/// </summary>
/// <param name="builder"></param>
/// <param name="redisConnectionString"></param>
/// <param name="name"></param>
/// <param name="failureStatus"></param>
/// <param name="tags"></param>
/// <param name="timeout"></param>
/// <returns></returns>
public static IHealthChecksBuilder AddRedis(this IHealthChecksBuilder builder, string redisConnectionString, string name = default, HealthStatus? failureStatus = default, IEnumerable<string> tags = default, TimeSpan? timeout = default)
{
return builder.Add(new HealthCheckRegistration(
name ?? NAME,
sp => new RedisHealthCheck(redisConnectionString),
failureStatus,
tags,
timeout));
}
}
public class RedisHealthCheck : IHealthCheck
{
private static readonly ConcurrentDictionary<string, ConnectionMultiplexer> Connections = new ConcurrentDictionary<string, ConnectionMultiplexer>();
private readonly string _redisConnectionString;
public RedisHealthCheck(string redisConnectionString)
{
_redisConnectionString = redisConnectionString ?? throw new ArgumentNullException(nameof(redisConnectionString));
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
try
{
if (!Connections.TryGetValue(_redisConnectionString, out ConnectionMultiplexer connection))
{
connection = await ConnectionMultiplexer.ConnectAsync(_redisConnectionString);
if (!Connections.TryAdd(_redisConnectionString, connection))
{
// Dispose new connection which we just created, because we don't need it.
connection.Dispose();
connection = Connections[_redisConnectionString];
}
}
await connection.GetDatabase()
.PingAsync();
if (!connection.IsConnected)
return new HealthCheckResult(context.Registration.FailureStatus, $"redis IsConnected is false");
return HealthCheckResult.Healthy();
}
catch (Exception ex)
{
return new HealthCheckResult(context.Registration.FailureStatus, exception: ex);
}
}
}
}