From e7917f8270981b47669966ed34c2a23f5c1e5d64 Mon Sep 17 00:00:00 2001 From: Bradley Grainger Date: Fri, 17 Nov 2023 07:07:43 -0800 Subject: [PATCH] Send a MySQL ping packet by default. Fixes #2031 Users can opt in to setting a command that will be executed on the server, but the default is now a more efficient ping. --- .../MySqlHealthCheckBuilderExtensions.cs | 9 ++++---- src/HealthChecks.MySql/MySqlHealthCheck.cs | 23 +++++++++++++------ .../MySqlHealthCheckOptions.cs | 3 +-- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/HealthChecks.MySql/DependencyInjection/MySqlHealthCheckBuilderExtensions.cs b/src/HealthChecks.MySql/DependencyInjection/MySqlHealthCheckBuilderExtensions.cs index 09e2fac106..0b755f37bd 100644 --- a/src/HealthChecks.MySql/DependencyInjection/MySqlHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.MySql/DependencyInjection/MySqlHealthCheckBuilderExtensions.cs @@ -10,14 +10,13 @@ namespace Microsoft.Extensions.DependencyInjection; public static class MySqlHealthCheckBuilderExtensions { private const string NAME = "mysql"; - internal const string HEALTH_QUERY = "SELECT 1;"; /// /// Add a health check for MySQL databases. /// /// The . /// The MySQL connection string to be used. - /// The query to be executed. + /// The optional query to be executed. If this is null, a MySQL "ping" packet will be sent to the server instead of a query. /// An optional action to allow additional MySQL specific configuration. /// The health check name. Optional. If null the type name 'mysql' will be used for the name. /// @@ -30,7 +29,7 @@ public static class MySqlHealthCheckBuilderExtensions public static IHealthChecksBuilder AddMySql( this IHealthChecksBuilder builder, string connectionString, - string healthQuery = HEALTH_QUERY, + string? healthQuery = null, Action? configure = null, string? name = default, HealthStatus? failureStatus = default, @@ -45,7 +44,7 @@ public static IHealthChecksBuilder AddMySql( /// /// The . /// A factory to build the MySQL connection string to use. - /// The query to be executed. + /// The optional query to be executed. If this is null, a MySQL "ping" packet will be sent to the server instead of a query. /// An optional action to allow additional MySQL specific configuration. /// The health check name. Optional. If null the type name 'mysql' will be used for the name. /// @@ -58,7 +57,7 @@ public static IHealthChecksBuilder AddMySql( public static IHealthChecksBuilder AddMySql( this IHealthChecksBuilder builder, Func connectionStringFactory, - string healthQuery = HEALTH_QUERY, + string? healthQuery = null, Action? configure = null, string? name = default, HealthStatus? failureStatus = default, diff --git a/src/HealthChecks.MySql/MySqlHealthCheck.cs b/src/HealthChecks.MySql/MySqlHealthCheck.cs index fb7f433193..8bb4b3b4a7 100644 --- a/src/HealthChecks.MySql/MySqlHealthCheck.cs +++ b/src/HealthChecks.MySql/MySqlHealthCheck.cs @@ -13,7 +13,6 @@ public class MySqlHealthCheck : IHealthCheck public MySqlHealthCheck(MySqlHealthCheckOptions options) { Guard.ThrowIfNull(options.ConnectionString, true); - Guard.ThrowIfNull(options.CommandText, true); _options = options; } @@ -27,13 +26,23 @@ public async Task CheckHealthAsync(HealthCheckContext context _options.Configure?.Invoke(connection); await connection.OpenAsync(cancellationToken).ConfigureAwait(false); - using var command = connection.CreateCommand(); - command.CommandText = _options.CommandText; - object? result = await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false); + if (_options.CommandText is { } commandText) + { + using var command = connection.CreateCommand(); + command.CommandText = _options.CommandText; + object? result = await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false); - return _options.HealthCheckResultBuilder == null - ? HealthCheckResult.Healthy() - : _options.HealthCheckResultBuilder(result); + return _options.HealthCheckResultBuilder == null + ? HealthCheckResult.Healthy() + : _options.HealthCheckResultBuilder(result); + } + else + { + var success = await connection.PingAsync(cancellationToken).ConfigureAwait(false); + return _options.HealthCheckResultBuilder is null + ? (success ? HealthCheckResult.Healthy() : new HealthCheckResult(context.Registration.FailureStatus)) : + _options.HealthCheckResultBuilder(success); + } } catch (Exception ex) { diff --git a/src/HealthChecks.MySql/MySqlHealthCheckOptions.cs b/src/HealthChecks.MySql/MySqlHealthCheckOptions.cs index d8a1f073d7..47d2629620 100644 --- a/src/HealthChecks.MySql/MySqlHealthCheckOptions.cs +++ b/src/HealthChecks.MySql/MySqlHealthCheckOptions.cs @@ -1,4 +1,3 @@ -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; using MySqlConnector; @@ -17,7 +16,7 @@ public class MySqlHealthCheckOptions /// /// The query to be executed. /// - public string CommandText { get; set; } = MySqlHealthCheckBuilderExtensions.HEALTH_QUERY; + public string? CommandText { get; set; } /// /// An optional action executed before the connection is opened in the health check.