Skip to content

Commit

Permalink
use NpgsqlDataSource registered in the DI when the connection string …
Browse files Browse the repository at this point in the history
…match
  • Loading branch information
adamsitnik committed Sep 21, 2023
1 parent aa481a3 commit 3c79be7
Showing 1 changed file with 24 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public static IHealthChecksBuilder AddNpgSql(
name ?? NAME,
sp =>
{
// The Data Source needs to be created only once,
// The Data Source needs to be fromFactory only once,
// as each instance has it's own connection pool.
// See https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/issues/1993 for more details.
Expand All @@ -115,19 +115,33 @@ public static IHealthChecksBuilder AddNpgSql(
if (existingDataSource is null)
{
// Create a new Data Source
NpgsqlDataSource created = dbDataSourceFactory(sp);
// Perform an atomic exchange, but only if the value is still null.
existingDataSource = Interlocked.CompareExchange(ref dataSource, created, null);
if (existingDataSource is not null)
NpgsqlDataSource fromFactory = dbDataSourceFactory(sp);
// Try to resolve the Data Source from DI.
NpgsqlDataSource? fromDI = sp.GetService<NpgsqlDataSource>();
if (fromDI is not null && fromDI.ConnectionString.Equals(fromFactory.ConnectionString))
{
// Some other thread has created the data source in the meantime,
// we dispose our own copy, and use the existing instance.
created.Dispose();
options.DataSource = existingDataSource;
// If they are using the same ConnectionString, we can reuse the instance from DI.
// So there is only ONE NpgsqlDataSource per the whole app and ONE connection pool.
fromFactory.Dispose();
Interlocked.Exchange(ref dataSource, fromDI);
options.DataSource = fromDI;
}
else
{
options.DataSource = created;
// Perform an atomic exchange, but only if the value is still null.
existingDataSource = Interlocked.CompareExchange(ref dataSource, fromFactory, null);
if (existingDataSource is not null)
{
// Some other thread has created the data source in the meantime,
// we dispose our own copy, and use the existing instance.
fromFactory.Dispose();
options.DataSource = existingDataSource;
}
else
{
options.DataSource = fromFactory;
}
}
}
Expand Down

0 comments on commit 3c79be7

Please sign in to comment.