Skip to content

Conversation

smbecker
Copy link
Contributor

What this PR does / why we need it: Adds health check support for ClickHouse

Does this PR introduce a user-facing change?: It adds a new package to support ClickHouse health checks

Please make sure you've completed the relevant tasks for this PR, out of the following list:

  • Code compiles correctly
  • Created/updated tests
  • Unit tests passing
  • End-to-end tests passing
  • Extended the documentation
  • Provided sample for the feature

@github-actions github-actions bot added github_actions Pull requests that update Github_actions code docs labels Nov 11, 2024
Copy link
Collaborator

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smbecker big thanks for your contribution! It looks like a step in the right direction, we just need to clarify how ClickHouseConnection should be used to ensure we provide the right API and of course solve the copy-paste errors.

{
try
{
await using var connection = _options.ConnectionFactory?.Invoke() ?? new ClickHouseConnection(_options.ConnectionString);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the recommendations for using ClickHouseConnection? Namely:

  • is it thread safe?
  • does it have a built-in pool of connections? (when we execute new ClickHouseConnection(_options.ConnectionString), does it always create a new coonection?)

I need to get a better understanding of how it should be used before I approve the shape of the public API for this DB.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it thread safe?

Looking at the code, instance methods on ClickHouseConnection do not appear to be thread-safe. However, commands do appear to be thread-safe in that they just execute HttpRequestMessages against the owned HttpClient.

does it have a built-in pool of connections?

It does not support pooling directly. However, when creating a ClickHouseConnection with a passed in HttpClient or IHttpClientFactory, you can take advantage of pooling within the HttpClient.

I could follow a similar pattern to Npgsql if/when this PR is merged.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smbecker thank you for checking everything and contributing a PR!

Based on what you wrote and https://github.com/DarkWanderer/ClickHouse.Client/wiki/Connection-lifetime-&-pooling#recommendations:

If an application operates on large volumes of transactions and requires to create/destroy ClickHouseConnection objects often, it is recommended to use IHttpClientFactory or a static instance of HttpClient to manage connections

I wonder if we should do the following:

  1. Recommend the users to use IHttpClientFactory in the README.md and show an example that registers ClickHouseConnection factory method along with the IHttpClientFactory (people just copy this code most of the time, this is why I would like it to be the "right" way of doing things)
  2. Have a single extension method that takes a mandatory Func<IServiceProvider, ClickHouseConnection> connectionFactory argument. It allows the user to obtain all kinds of configuration options from the service provider and forces them to create ClickHouseConnection on their own.
public static IHealthChecksBuilder AddClickHouse(
    this IHealthChecksBuilder builder,
    Func<IServiceProvider, ClickHouseConnection> connectionFactory,
    string healthQuery = HEALTH_QUERY,
    Action<ClickHouseConnection>? configure = null,
    string? name = default,
    HealthStatus? failureStatus = default,
    IEnumerable<string>? tags = default,
    TimeSpan? timeout = default)

@smbecker what do you think?

Copy link
Collaborator

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PTAL at my comments. Overall the PR is high quality contribution, I just want us to make sure we introduce the best API design from day one.

Again, thank you @smbecker !

{
try
{
await using var connection = _options.ConnectionFactory?.Invoke() ?? new ClickHouseConnection(_options.ConnectionString);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smbecker thank you for checking everything and contributing a PR!

Based on what you wrote and https://github.com/DarkWanderer/ClickHouse.Client/wiki/Connection-lifetime-&-pooling#recommendations:

If an application operates on large volumes of transactions and requires to create/destroy ClickHouseConnection objects often, it is recommended to use IHttpClientFactory or a static instance of HttpClient to manage connections

I wonder if we should do the following:

  1. Recommend the users to use IHttpClientFactory in the README.md and show an example that registers ClickHouseConnection factory method along with the IHttpClientFactory (people just copy this code most of the time, this is why I would like it to be the "right" way of doing things)
  2. Have a single extension method that takes a mandatory Func<IServiceProvider, ClickHouseConnection> connectionFactory argument. It allows the user to obtain all kinds of configuration options from the service provider and forces them to create ClickHouseConnection on their own.
public static IHealthChecksBuilder AddClickHouse(
    this IHealthChecksBuilder builder,
    Func<IServiceProvider, ClickHouseConnection> connectionFactory,
    string healthQuery = HEALTH_QUERY,
    Action<ClickHouseConnection>? configure = null,
    string? name = default,
    HealthStatus? failureStatus = default,
    IEnumerable<string>? tags = default,
    TimeSpan? timeout = default)

@smbecker what do you think?

@smbecker
Copy link
Contributor Author

I took your recommendations for the most part. Please take a look and let me know if I missed anything.

Copy link
Collaborator

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you very much for your contribution @smbecker !

@adamsitnik adamsitnik merged commit e8730db into Xabaril:master Dec 11, 2024
55 of 56 checks passed
@adamsitnik adamsitnik added this to the 9.0 milestone Dec 11, 2024
@smbecker
Copy link
Contributor Author

Thanks for collaborating on it with me!

@smbecker smbecker deleted the sb-clickhouse branch December 11, 2024 16:16
@codecov-commenter
Copy link

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 66.65%. Comparing base (72d9abf) to head (8b98bd6).
Report is 35 commits behind head on master.

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2315      +/-   ##
==========================================
- Coverage   66.88%   66.65%   -0.24%     
==========================================
  Files         268      255      -13     
  Lines        8730     8600     -130     
  Branches      631      617      -14     
==========================================
- Hits         5839     5732     -107     
+ Misses       2723     2702      -21     
+ Partials      168      166       -2     
Flag Coverage Δ
ApplicationStatus 3.77% <ø> (-24.90%) ⬇️
ArangoDb 3.77% <ø> (-24.53%) ⬇️
Aws.S3 3.77% <ø> (-11.76%) ⬇️
Aws.SecretsManager 3.77% <ø> (-12.05%) ⬇️
Aws.Sns 3.77% <ø> (-12.21%) ⬇️
Aws.Sqs 3.77% <ø> (-12.90%) ⬇️
Aws.SystemsManager 3.77% <ø> (-12.05%) ⬇️
Azure.IoTHub 3.77% <ø> (-10.06%) ⬇️
AzureApplicationInsights 5.66% <ø> (-10.91%) ⬇️
AzureBlobStorage ?
AzureDigitalTwin 5.66% <ø> (-31.50%) ⬇️
AzureEventHubs ?
AzureFileStorage ?
AzureKeyVault 5.66% <ø> (-24.83%) ⬇️
AzureQueueStorage ?
AzureSearch 3.77% <ø> (-13.84%) ⬇️
AzureServiceBus 3.77% <ø> (-68.72%) ⬇️
AzureTableStorage ?
Consul 3.77% <ø> (-20.56%) ⬇️
CosmosDb 3.77% <ø> (-25.68%) ⬇️
Dapr 0.00% <ø> (-14.51%) ⬇️
DynamoDb 3.77% <ø> (-9.52%) ⬇️
Elasticsearch 3.77% <ø> (-43.90%) ⬇️
EventStore 56.60% <ø> (-8.54%) ⬇️
EventStore.gRPC 0.00% <ø> (-25.52%) ⬇️
Gcp.CloudFirestore 3.77% <ø> (-9.56%) ⬇️
Gremlin 25.00% <ø> (ø)
Hangfire 3.53% <ø> (-8.57%) ⬇️
IbmMQ 4.42% <ø> (-26.35%) ⬇️
InfluxDB 0.00% <ø> (-15.55%) ⬇️
Kafka 3.77% <ø> (-19.76%) ⬇️
Kubernetes 41.54% <ø> (ø)
Milvus 3.77% <ø> (-13.02%) ⬇️
MongoDb 3.77% <ø> (-29.08%) ⬇️
MySql 3.77% <ø> (-29.56%) ⬇️
Nats 61.32% <ø> (-11.46%) ⬇️
Npgsql 3.77% <ø> (-40.45%) ⬇️
OpenIdConnectServer 42.48% <ø> (ø)
Oracle 56.60% <ø> (-7.33%) ⬇️
Prometheus.Metrics 0.00% <ø> (-29.81%) ⬇️
Publisher.ApplicationInsights 0.00% <ø> (-15.28%) ⬇️
Publisher.CloudWatch 3.77% <ø> (-16.57%) ⬇️
Publisher.Datadog 3.77% <ø> (-13.43%) ⬇️
Publisher.Prometheus 3.77% <ø> (-14.98%) ⬇️
Publisher.Seq 3.77% <ø> (-36.97%) ⬇️
Qdrant 3.77% <ø> (-14.49%) ⬇️
RabbitMQ 4.42% <ø> (-46.22%) ⬇️
Redis 56.60% <ø> (-11.87%) ⬇️
SendGrid 3.77% <ø> (-13.45%) ⬇️
SignalR 25.97% <ø> (ø)
SqlServer 3.77% <ø> (-26.67%) ⬇️
Sqlite 25.88% <ø> (ø)
System 11.50% <ø> (-32.09%) ⬇️
UI 85.84% <ø> (+19.97%) ⬆️
Uris 56.60% <ø> (-5.55%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs github_actions Pull requests that update Github_actions code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants