Skip to content

Commit

Permalink
Try to use qdrant-client health check
Browse files Browse the repository at this point in the history
  • Loading branch information
Alirexaa committed Oct 30, 2024
1 parent 3bbc346 commit 0282e14
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 38 deletions.
4 changes: 4 additions & 0 deletions src/Aspire.Hosting.Qdrant/Aspire.Hosting.Qdrant.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@
<ItemGroup>
<ProjectReference Include="..\Aspire.Hosting\Aspire.Hosting.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Qdrant.Client" />
</ItemGroup>
</Project>
17 changes: 7 additions & 10 deletions src/Aspire.Hosting.Qdrant/QdrantBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Aspire.Qdrant.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Qdrant.Client;

namespace Aspire.Hosting;

Expand Down Expand Up @@ -47,20 +48,21 @@ public static IResourceBuilder<QdrantServerResource> AddQdrant(this IDistributed
ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(builder, $"{name}-Key", special: false);
var qdrant = new QdrantServerResource(name, apiKeyParameter);

HttpClient? httpClient = null;
QdrantClient? qdrantClient = null;

builder.Eventing.Subscribe<ConnectionStringAvailableEvent>(qdrant, async (@event, ct) =>
{
var connectionString = await qdrant.HttpConnectionStringExpression.GetValueAsync(ct).ConfigureAwait(false)
?? throw new DistributedApplicationException($"ConnectionStringAvailableEvent was published for the '{qdrant.Name}' resource but the connection string was null.");
httpClient = CreateQdrantHttpClient(connectionString);
qdrantClient = CreateQdrantClient(connectionString);
});

var healthCheckKey = $"{name}_check";
builder.Services.AddHealthChecks()
.Add(new HealthCheckRegistration(
healthCheckKey,
sp => new QdrantHealthCheck(httpClient!),
sp => new QdrantHealthCheck(qdrantClient!),
failureStatus: default,
tags: default,
timeout: default));
Expand Down Expand Up @@ -142,7 +144,7 @@ public static IResourceBuilder<TDestination> WithReference<TDestination>(this IR
return builder;
}

private static HttpClient CreateQdrantHttpClient(string? connectionString)
private static QdrantClient CreateQdrantClient(string? connectionString)
{
if (connectionString is null)
{
Expand Down Expand Up @@ -174,12 +176,7 @@ private static HttpClient CreateQdrantHttpClient(string? connectionString)
}
}

var client = new HttpClient();
client.BaseAddress = endpoint;
if (key is not null)
{
client.DefaultRequestHeaders.Add("Api-Key", key);
}
var client = new QdrantClient(endpoint!, key);
return client;
}
}
26 changes: 3 additions & 23 deletions src/Components/Aspire.Qdrant.Client/AspireQdrantExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,33 +84,13 @@ private static void AddQdrant(

if (!settings.DisableHealthChecks)
{
// use http client for register health check
var httpClientName = serviceKey is null ? "qdrant-healthchecks" : $"qdrant-healthchecks_{connectionName}";
builder.Services.AddHttpClient(
httpClientName,
client =>
{
if (settings.Endpoint is null)
{
throw new InvalidOperationException(
$"A QdrantClient could not be configured. Ensure valid connection information was provided in 'ConnectionStrings:{connectionName}' or either " +
$"{nameof(settings.Endpoint)} must be provided " +
$"in the '{DefaultConfigSectionName}' or '{DefaultConfigSectionName}:{connectionName}' configuration section.");
}
client.BaseAddress = settings.Endpoint;
if (settings.Key is not null)
{
client.DefaultRequestHeaders.Add("Api-Key", settings.Key);
}
});

var healthCheckName = serviceKey is null ? "Qdrant.Client" : $"Qdrant.Client_{connectionName}";

builder.TryAddHealthCheck(new HealthCheckRegistration(
healthCheckName,
sp => new QdrantHealthCheck(sp.GetRequiredService<IHttpClientFactory>().CreateClient(httpClientName)),
sp => new QdrantHealthCheck(serviceKey is null ?
sp.GetRequiredService<QdrantClient>() :
sp.GetRequiredKeyedService<QdrantClient>(serviceKey)),
failureStatus: null,
tags: null,
timeout: settings.HealthCheckTimeout > 0 ? TimeSpan.FromMilliseconds(settings.HealthCheckTimeout.Value) : null
Expand Down
9 changes: 5 additions & 4 deletions src/Components/Aspire.Qdrant.Client/QdrantHealthCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.Extensions.Diagnostics.HealthChecks;
using Qdrant.Client;

namespace Aspire.Qdrant.Client;
internal sealed class QdrantHealthCheck : IHealthCheck
{
private readonly HttpClient _client;
private readonly QdrantClient _client;

public QdrantHealthCheck(HttpClient client)
public QdrantHealthCheck(QdrantClient client)
{
ArgumentNullException.ThrowIfNull(client, nameof(client));
_client = client;
Expand All @@ -18,9 +19,9 @@ public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context
{
try
{
var response = await _client.GetAsync("/readyz", cancellationToken).ConfigureAwait(false);
var response = await _client.HealthAsync(cancellationToken).ConfigureAwait(false);

return response.IsSuccessStatusCode
return !(response is null || response.Title is null)
? HealthCheckResult.Healthy()
: new HealthCheckResult(HealthStatus.Unhealthy);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/Aspire.Qdrant.Client.Tests/QdrantContainerFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public async Task InitializeAsync()
_apiKey = PasswordGenerator.Generate(minLength: 16, lower: true, upper: true, numeric: true, special: false, minLower: 1, minUpper: 1, minNumeric: 1, minSpecial: 0);

Container = new ContainerBuilder()
.WithImage($"{TestConstants.AspireTestContainerRegistry}/{QdrantContainerImageTags.Image}:{QdrantContainerImageTags.Tag}")
.WithImage($"{ComponentTestConstants.AspireTestContainerRegistry}/{QdrantContainerImageTags.Image}:{QdrantContainerImageTags.Tag}")
.WithPortBinding(6333, true)
.WithWaitStrategy(Wait.ForUnixContainer().UntilHttpRequestIsSucceeded(r => r.ForPort(6333)))
.WithEnvironment("QDRANT__SERVICE__API_KEY", _apiKey)
Expand Down

0 comments on commit 0282e14

Please sign in to comment.