Skip to content

Commit 32fc88f

Browse files
authored
Expose NpgsqlDataSource.Clear() publicly (#5903)
Closes #5902
1 parent 32eb709 commit 32fc88f

File tree

7 files changed

+50
-25
lines changed

7 files changed

+50
-25
lines changed

src/Npgsql/MultiHostDataSourceWrapper.cs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,12 @@
77

88
namespace Npgsql;
99

10-
sealed class MultiHostDataSourceWrapper : NpgsqlDataSource
10+
sealed class MultiHostDataSourceWrapper(NpgsqlMultiHostDataSource wrappedSource, TargetSessionAttributes targetSessionAttributes)
11+
: NpgsqlDataSource(CloneSettingsForTargetSessionAttributes(wrappedSource.Settings, targetSessionAttributes), wrappedSource.Configuration)
1112
{
1213
internal override bool OwnsConnectors => false;
1314

14-
readonly NpgsqlMultiHostDataSource _wrappedSource;
15-
16-
public MultiHostDataSourceWrapper(NpgsqlMultiHostDataSource source, TargetSessionAttributes targetSessionAttributes)
17-
: base(CloneSettingsForTargetSessionAttributes(source.Settings, targetSessionAttributes), source.Configuration)
18-
=> _wrappedSource = source;
15+
public override void Clear() => wrappedSource.Clear();
1916

2017
static NpgsqlConnectionStringBuilder CloneSettingsForTargetSessionAttributes(
2118
NpgsqlConnectionStringBuilder settings,
@@ -26,23 +23,22 @@ static NpgsqlConnectionStringBuilder CloneSettingsForTargetSessionAttributes(
2623
return clonedSettings;
2724
}
2825

29-
internal override (int Total, int Idle, int Busy) Statistics => _wrappedSource.Statistics;
26+
internal override (int Total, int Idle, int Busy) Statistics => wrappedSource.Statistics;
3027

31-
internal override void Clear() => _wrappedSource.Clear();
3228
internal override ValueTask<NpgsqlConnector> Get(NpgsqlConnection conn, NpgsqlTimeout timeout, bool async, CancellationToken cancellationToken)
33-
=> _wrappedSource.Get(conn, timeout, async, cancellationToken);
29+
=> wrappedSource.Get(conn, timeout, async, cancellationToken);
3430
internal override bool TryGetIdleConnector([NotNullWhen(true)] out NpgsqlConnector? connector)
3531
=> throw new NpgsqlException("Npgsql bug: trying to get an idle connector from " + nameof(MultiHostDataSourceWrapper));
3632
internal override ValueTask<NpgsqlConnector?> OpenNewConnector(NpgsqlConnection conn, NpgsqlTimeout timeout, bool async, CancellationToken cancellationToken)
3733
=> throw new NpgsqlException("Npgsql bug: trying to open a new connector from " + nameof(MultiHostDataSourceWrapper));
3834
internal override void Return(NpgsqlConnector connector)
39-
=> _wrappedSource.Return(connector);
35+
=> wrappedSource.Return(connector);
4036

4137
internal override void AddPendingEnlistedConnector(NpgsqlConnector connector, Transaction transaction)
42-
=> _wrappedSource.AddPendingEnlistedConnector(connector, transaction);
38+
=> wrappedSource.AddPendingEnlistedConnector(connector, transaction);
4339
internal override bool TryRemovePendingEnlistedConnector(NpgsqlConnector connector, Transaction transaction)
44-
=> _wrappedSource.TryRemovePendingEnlistedConnector(connector, transaction);
40+
=> wrappedSource.TryRemovePendingEnlistedConnector(connector, transaction);
4541
internal override bool TryRentEnlistedPending(Transaction transaction, NpgsqlConnection connection,
4642
[NotNullWhen(true)] out NpgsqlConnector? connector)
47-
=> _wrappedSource.TryRentEnlistedPending(transaction, connection, out connector);
48-
}
43+
=> wrappedSource.TryRentEnlistedPending(transaction, connection, out connector);
44+
}

src/Npgsql/NpgsqlDataSource.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,12 @@ protected override DbBatch CreateDbBatch()
208208
public new NpgsqlBatch CreateBatch()
209209
=> new NpgsqlDataSourceBatch(CreateConnection());
210210

211+
/// <summary>
212+
/// If the data source pools connections, clears any idle connections and flags any busy connections to be closed as soon as they're
213+
/// returned to the pool.
214+
/// </summary>
215+
public abstract void Clear();
216+
211217
/// <summary>
212218
/// Creates a new <see cref="NpgsqlDataSource" /> for the given <paramref name="connectionString" />.
213219
/// </summary>
@@ -371,8 +377,6 @@ internal abstract ValueTask<NpgsqlConnector> Get(
371377

372378
internal abstract void Return(NpgsqlConnector connector);
373379

374-
internal abstract void Clear();
375-
376380
internal abstract bool OwnsConnectors { get; }
377381

378382
#region Database state management

src/Npgsql/NpgsqlMultiHostDataSource.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,8 @@ internal override bool TryGetIdleConnector([NotNullWhen(true)] out NpgsqlConnect
363363
internal override ValueTask<NpgsqlConnector?> OpenNewConnector(NpgsqlConnection conn, NpgsqlTimeout timeout, bool async, CancellationToken cancellationToken)
364364
=> throw new NpgsqlException("Npgsql bug: trying to open a new connector from " + nameof(NpgsqlMultiHostDataSource));
365365

366-
internal override void Clear()
366+
/// <inheritdoc />
367+
public override void Clear()
367368
{
368369
foreach (var pool in _pools)
369370
pool.Clear();

src/Npgsql/PoolingDataSource.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ internal sealed override void Return(NpgsqlConnector connector)
335335
Debug.Assert(written);
336336
}
337337

338-
internal override void Clear()
338+
public override void Clear()
339339
{
340340
Interlocked.Increment(ref _clearCounter);
341341

src/Npgsql/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#nullable enable
2+
abstract Npgsql.NpgsqlDataSource.Clear() -> void
23
Npgsql.NpgsqlConnection.CloneWithAsync(string! connectionString, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask<Npgsql.NpgsqlConnection!>
34
Npgsql.NpgsqlConnection.SslClientAuthenticationOptionsCallback.get -> System.Action<System.Net.Security.SslClientAuthenticationOptions!>?
45
Npgsql.NpgsqlConnection.SslClientAuthenticationOptionsCallback.set -> void
@@ -35,3 +36,4 @@ Npgsql.Replication.PgOutput.PgOutputStreamingMode.Parallel = 2 -> Npgsql.Replica
3536
Npgsql.SslNegotiation
3637
Npgsql.SslNegotiation.Direct = 1 -> Npgsql.SslNegotiation
3738
Npgsql.SslNegotiation.Postgres = 0 -> Npgsql.SslNegotiation
39+
override Npgsql.NpgsqlMultiHostDataSource.Clear() -> void

src/Npgsql/UnpooledDataSource.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,9 @@
66

77
namespace Npgsql;
88

9-
sealed class UnpooledDataSource : NpgsqlDataSource
9+
sealed class UnpooledDataSource(NpgsqlConnectionStringBuilder settings, NpgsqlDataSourceConfiguration dataSourceConfig)
10+
: NpgsqlDataSource(settings, dataSourceConfig)
1011
{
11-
public UnpooledDataSource(NpgsqlConnectionStringBuilder settings, NpgsqlDataSourceConfiguration dataSourceConfig)
12-
: base(settings, dataSourceConfig)
13-
{
14-
}
15-
1612
volatile int _numConnectors;
1713

1814
internal override (int Total, int Idle, int Busy) Statistics => (_numConnectors, 0, _numConnectors);
@@ -46,5 +42,7 @@ internal override void Return(NpgsqlConnector connector)
4642
connector.Close();
4743
}
4844

49-
internal override void Clear() {}
45+
public override void Clear()
46+
{
47+
}
5048
}

test/Npgsql.Tests/DataSourceTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,30 @@ public async Task ExecuteReader_on_connectionless_batch([Values] bool async)
134134
Assert.That(dataSource.Statistics, Is.EqualTo((Total: 1, Idle: 1, Busy: 0)));
135135
}
136136

137+
[Test]
138+
public void Clear()
139+
{
140+
using var dataSource = NpgsqlDataSource.Create(ConnectionString);
141+
var connection1 = dataSource.OpenConnection();
142+
var connection2 = dataSource.OpenConnection();
143+
connection1.Close();
144+
145+
Assert.That(dataSource.Statistics, Is.EqualTo((Total: 2, Idle: 1, Busy: 1)));
146+
147+
dataSource.Clear();
148+
149+
Assert.That(dataSource.Statistics, Is.EqualTo((Total: 1, Idle: 0, Busy: 1)));
150+
151+
var connection3 = dataSource.OpenConnection();
152+
Assert.That(dataSource.Statistics, Is.EqualTo((Total: 2, Idle: 0, Busy: 2)));
153+
154+
connection2.Close();
155+
Assert.That(dataSource.Statistics, Is.EqualTo((Total: 1, Idle: 0, Busy: 1)));
156+
157+
connection3.Close();
158+
Assert.That(dataSource.Statistics, Is.EqualTo((Total: 1, Idle: 1, Busy: 0)));
159+
}
160+
137161
[Test]
138162
public void Dispose()
139163
{

0 commit comments

Comments
 (0)