Skip to content

Commit

Permalink
Swap around the versions now that we are going to release a 9.0 major…
Browse files Browse the repository at this point in the history
… version.

Update to latest master branch.
  • Loading branch information
eerhardt committed Dec 5, 2024
1 parent 3e614f1 commit 6f1ffaa
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 155 deletions.
4 changes: 2 additions & 2 deletions AspNetCore.Diagnostics.HealthChecks.sln
Original file line number Diff line number Diff line change
Expand Up @@ -311,9 +311,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.Milvus", "src\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.Milvus.Tests", "test\HealthChecks.Milvus.Tests\HealthChecks.Milvus.Tests.csproj", "{D49CF52C-9D21-4D98-8A15-A2B259E9C003}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthChecks.Rabbitmq.v7", "src\HealthChecks.Rabbitmq.v7\HealthChecks.Rabbitmq.v7.csproj", "{C76D7349-A3D2-7277-93C6-EE92E8E447A5}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthChecks.Rabbitmq.v6", "src\HealthChecks.Rabbitmq.v6\HealthChecks.Rabbitmq.v6.csproj", "{C76D7349-A3D2-7277-93C6-EE92E8E447A5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthChecks.RabbitMQ.v7.Tests", "test\HealthChecks.RabbitMQ.v7.Tests\HealthChecks.RabbitMQ.v7.Tests.csproj", "{2787F63E-ABEA-9461-CDF3-97FE7C5C3DCC}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthChecks.RabbitMQ.v6.Tests", "test\HealthChecks.RabbitMQ.v6.Tests\HealthChecks.RabbitMQ.v6.Tests.csproj", "{2787F63E-ABEA-9461-CDF3-97FE7C5C3DCC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
<PackageVersion Include="prometheus-net" Version="8.1.0" />
<PackageVersion Include="PublicApiGenerator" Version="11.0.0" />
<PackageVersion Include="Qdrant.Client" Version="1.12.0" />
<PackageVersion Include="RabbitMQ.Client" Version="6.8.1" />
<PackageVersion Include="RabbitMQ.Client" Version="7.0.0" />
<PackageVersion Include="RavenDB.Client" Version="6.0.1" />
<PackageVersion Include="RichardSzalay.MockHttp" Version="7.0.0" />
<PackageVersion Include="Roslynator.Analyzers" Version="4.7.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
<PropertyGroup>
<TargetFrameworks>$(DefaultLibraryTargetFrameworks)</TargetFrameworks>
<PackageTags>$(PackageTags);RabbitMQ</PackageTags>
<Description>HealthChecks.RabbitMQ is the health check package for RabbitMQ.Client (version 7+).</Description>
<Description>HealthChecks.RabbitMQ is the health check package for RabbitMQ.Client (version 6).</Description>
<VersionPrefix>$(HealthCheckRabbitMQ)</VersionPrefix>
<AssemblyName>HealthChecks.Rabbitmq</AssemblyName>
<RootNamespace>HealthChecks.RabbitMQ</RootNamespace> <!--For backward naming compatibility-->
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="RabbitMQ.Client" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="8.0.0" />
<PackageReference Include="RabbitMQ.Client" VersionOverride="6.8.1" />

<Compile Include="../HealthCheckResultTask.cs" />
<Compile Include="../HealthChecks.Rabbitmq/DependencyInjection/RabbitMQHealthCheckBuilderExtensions.cs" Link="DependencyInjection/RabbitMQHealthCheckBuilderExtensions.cs" />
Expand Down
74 changes: 74 additions & 0 deletions src/HealthChecks.Rabbitmq.v6/RabbitMQHealthCheck.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System.Collections.Concurrent;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using RabbitMQ.Client;

namespace HealthChecks.RabbitMQ;

/// <summary>
/// A health check for RabbitMQ services.
/// </summary>
public class RabbitMQHealthCheck : IHealthCheck
{
private static readonly ConcurrentDictionary<RabbitMQHealthCheckOptions, IConnection> _connections = new();

private IConnection? _connection;
private readonly RabbitMQHealthCheckOptions _options;

public RabbitMQHealthCheck(RabbitMQHealthCheckOptions options)
{
_options = Guard.ThrowIfNull(options);
_connection = options.Connection;

if (_connection is null && _options.ConnectionFactory is null && _options.ConnectionUri is null)
{
throw new ArgumentException("A connection, connection factory, or connection string must be set!", nameof(options));
}
}

/// <inheritdoc />
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
// TODO: cancellationToken unused, see https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/issues/714
try
{
using var model = EnsureConnection().CreateModel();
return HealthCheckResultTask.Healthy;
}
catch (Exception ex)
{
return Task.FromResult(new HealthCheckResult(context.Registration.FailureStatus, exception: ex));
}
}

private IConnection EnsureConnection()
{
_connection ??= _connections.GetOrAdd(_options, _ =>
{
var factory = _options.ConnectionFactory;

if (factory is null)
{
Guard.ThrowIfNull(_options.ConnectionUri);
factory = new ConnectionFactory
{
Uri = _options.ConnectionUri,
AutomaticRecoveryEnabled = true
};

if (_options.RequestedConnectionTimeout is not null)
{
((ConnectionFactory)factory).RequestedConnectionTimeout = _options.RequestedConnectionTimeout.Value;
}

if (_options.Ssl is not null)
{
((ConnectionFactory)factory).Ssl = _options.Ssl;
}
}

return factory.CreateConnection();
});

return _connection;
}
}
113 changes: 0 additions & 113 deletions src/HealthChecks.Rabbitmq.v7/RabbitMQHealthCheck.cs

This file was deleted.

2 changes: 1 addition & 1 deletion src/HealthChecks.Rabbitmq/HealthChecks.Rabbitmq.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFrameworks>$(DefaultLibraryTargetFrameworks)</TargetFrameworks>
<PackageTags>$(PackageTags);RabbitMQ</PackageTags>
<Description>HealthChecks.RabbitMQ is the health check package for RabbitMQ.</Description>
<Description>HealthChecks.RabbitMQ is the health check package for RabbitMQ.Client.</Description>
<VersionPrefix>$(HealthCheckRabbitMQ)</VersionPrefix>
<RootNamespace>HealthChecks.RabbitMQ</RootNamespace> <!--For backward naming compatibility-->
</PropertyGroup>
Expand Down
97 changes: 68 additions & 29 deletions src/HealthChecks.Rabbitmq/RabbitMQHealthCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace HealthChecks.RabbitMQ;
/// </summary>
public class RabbitMQHealthCheck : IHealthCheck
{
private static readonly ConcurrentDictionary<RabbitMQHealthCheckOptions, IConnection> _connections = new();
private static readonly ConcurrentDictionary<RabbitMQHealthCheckOptions, Task<IConnection>> _connections = new();

private IConnection? _connection;
private readonly RabbitMQHealthCheckOptions _options;
Expand All @@ -26,49 +26,88 @@ public RabbitMQHealthCheck(RabbitMQHealthCheckOptions options)
}

/// <inheritdoc />
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
// TODO: cancellationToken unused, see https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/issues/714
try
{
using var model = EnsureConnection().CreateModel();
return HealthCheckResultTask.Healthy;
var connection = await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);
await using var model = await connection.CreateChannelAsync(cancellationToken: cancellationToken).ConfigureAwait(false);

return HealthCheckResult.Healthy();
}
catch (Exception ex)
{
return Task.FromResult(new HealthCheckResult(context.Registration.FailureStatus, exception: ex));
return new HealthCheckResult(context.Registration.FailureStatus, exception: ex);
}
}

private IConnection EnsureConnection()
{
_connection ??= _connections.GetOrAdd(_options, _ =>
{
var factory = _options.ConnectionFactory;
private async Task<IConnection> EnsureConnectionAsync(CancellationToken cancellationToken) =>
_connection ??= await _connections.GetOrAddAsync(_options, async options =>
{
var factory = options.ConnectionFactory;

if (factory is null)
if (factory is null)
{
Guard.ThrowIfNull(options.ConnectionUri);
factory = new ConnectionFactory
{
Guard.ThrowIfNull(_options.ConnectionUri);
factory = new ConnectionFactory
{
Uri = _options.ConnectionUri,
AutomaticRecoveryEnabled = true
};
Uri = options.ConnectionUri,
AutomaticRecoveryEnabled = true
};

if (_options.RequestedConnectionTimeout is not null)
{
((ConnectionFactory)factory).RequestedConnectionTimeout = _options.RequestedConnectionTimeout.Value;
}
if (options.RequestedConnectionTimeout is not null)
{
((ConnectionFactory)factory).RequestedConnectionTimeout = options.RequestedConnectionTimeout.Value;
}

if (_options.Ssl is not null)
{
((ConnectionFactory)factory).Ssl = _options.Ssl;
}
if (options.Ssl is not null)
{
((ConnectionFactory)factory).Ssl = options.Ssl;
}
}

return factory.CreateConnection();
});
return await factory.CreateConnectionAsync(cancellationToken).ConfigureAwait(false);
}).ConfigureAwait(false);
}

return _connection;
internal static class ConcurrentDictionaryExtensions
{
/// <summary>
/// Provides an alternative to <see cref="ConcurrentDictionary{TKey, TValue}.GetOrAdd(TKey, Func{TKey, TValue})"/> specifically for asynchronous values. The factory method will only run once.
/// </summary>
public static async Task<TValue> GetOrAddAsync<TKey, TValue>(
this ConcurrentDictionary<TKey, Task<TValue>> dictionary,
TKey key,
Func<TKey, Task<TValue>> valueFactory) where TKey : notnull
{
while (true)
{
if (dictionary.TryGetValue(key, out var task))
{
return await task.ConfigureAwait(false);
}

// This is the task that we'll return to all waiters. We'll complete it when the factory is complete
var tcs = new TaskCompletionSource<TValue>(TaskCreationOptions.RunContinuationsAsynchronously);
if (dictionary.TryAdd(key, tcs.Task))
{
try
{
var value = await valueFactory(key).ConfigureAwait(false);
tcs.TrySetResult(value);
return await tcs.Task.ConfigureAwait(false);
}
catch (Exception ex)
{
// Make sure all waiters see the exception
tcs.SetException(ex);

// We remove the entry if the factory failed so it's not a permanent failure
// and future gets can retry (this could be a pluggable policy)
dictionary.TryRemove(key, out _);
throw;
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<DefineConstants>$(DefineConstants);RABBITMQ_V6</DefineConstants>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\HealthChecks.Rabbitmq\HealthChecks.Rabbitmq.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

<PropertyGroup>
<AssemblyName>HealthChecks.RabbitMQ.Tests</AssemblyName>
<DefineConstants>$(DefineConstants);RABBITMQ_V6</DefineConstants>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\HealthChecks.Rabbitmq.v7\HealthChecks.Rabbitmq.v7.csproj" />
<ProjectReference Include="..\..\src\HealthChecks.Rabbitmq.v6\HealthChecks.Rabbitmq.v6.csproj" />

<Compile Include="../HealthChecks.RabbitMQ.Tests/DependencyInjection/RegistrationTests.cs" Link="DependencyInjection/RegistrationTests.cs" />
<Compile Include="../HealthChecks.RabbitMQ.Tests/Functional/RabbitHealthCheckTests.cs" Link="Functional/RabbitHealthCheckTests.cs" />
Expand Down

0 comments on commit 6f1ffaa

Please sign in to comment.