Skip to content

Commit 9b00a0d

Browse files
authored
Merge pull request #149 from driseley/connection-leak-148
Fix for Connection leak issue
2 parents bae4753 + e4d96bf commit 9b00a0d

2 files changed

Lines changed: 55 additions & 8 deletions

File tree

src/AdoNetCore.AseClient/Internal/ConnectionPool.cs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,28 @@ public IInternalConnection Reserve(IInfoMessageEventNotifier eventNotifier)
6464
throw new OperationCanceledException();
6565
}
6666

67-
connection.ChangeDatabase(_parameters.Database);
68-
connection.SetTextSize(_parameters.TextSize);
69-
connection.NamedParameters = _parameters.NamedParameters;
70-
71-
if (_parameters.AnsiNull)
67+
try
68+
{
69+
connection.ChangeDatabase(_parameters.Database);
70+
connection.SetTextSize(_parameters.TextSize);
71+
connection.NamedParameters = _parameters.NamedParameters;
72+
73+
if (_parameters.AnsiNull)
74+
{
75+
connection.SetAnsiNull(_parameters.AnsiNull);
76+
}
77+
}
78+
catch (Exception)
7279
{
73-
connection.SetAnsiNull(_parameters.AnsiNull);
80+
if(_parameters.Pooling)
81+
{
82+
RemoveConnection(connection);
83+
}
84+
else
85+
{
86+
connection?.Dispose();
87+
}
88+
throw;
7489
}
7590

7691
return connection;

test/AdoNetCore.AseClient.Tests/Unit/ConnectionPoolTests.cs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,24 @@ public void WhenMinPoolSizeIsSet_NewPoolFillsToMin()
4646
Assert.AreEqual(10, pool.PoolSize);
4747
}
4848

49+
[Test]
50+
public void WhenChangeDatabaseThrows_PoolDoesNotLeak()
51+
{
52+
var parameters = new TestConnectionParameters
53+
{
54+
MaxPoolSize = 5,
55+
LoginTimeout = 1
56+
};
57+
58+
var pool = new ConnectionPool(parameters, new ImmediateConnectionFactory(changeDatabaseThrows: true));
59+
60+
for (int i=0; i<5; i++)
61+
{
62+
Assert.Throws<AseException>(() => pool.Reserve(null));
63+
}
64+
Assert.AreEqual(0, pool.PoolSize);
65+
}
66+
4967
[Test]
5068
public void NewOpenCall_TimesOut_ShouldThrow()
5169
{
@@ -155,16 +173,27 @@ public void PoolSpam_Blitz(short size, int threads)
155173

156174
private class ImmediateConnectionFactory : IInternalConnectionFactory
157175
{
176+
private readonly bool _changeDatabaseThrows;
177+
178+
public ImmediateConnectionFactory(bool changeDatabaseThrows = false)
179+
{
180+
_changeDatabaseThrows = changeDatabaseThrows;
181+
}
158182
public async Task<IInternalConnection> GetNewConnection(CancellationToken token, IInfoMessageEventNotifier eventNotifier)
159183
{
160-
return await Task.FromResult<IInternalConnection>(new DoNothingInternalConnection());
184+
return await Task.FromResult<IInternalConnection>(new DoNothingInternalConnection(_changeDatabaseThrows));
161185
}
162186
}
163187

164188
[SuppressMessage("ReSharper", "UnassignedGetOnlyAutoProperty")]
165189
[SuppressMessage("ReSharper", "UnusedMember.Local")]
166190
private class DoNothingInternalConnection : IInternalConnection
167191
{
192+
private readonly bool _changeDatabaseThrows;
193+
public DoNothingInternalConnection(bool changeDatabaseThrows = false)
194+
{
195+
_changeDatabaseThrows = changeDatabaseThrows;
196+
}
168197
public void Dispose() { }
169198
public DateTime Created { get; }
170199
public DateTime LastActive { get; }
@@ -174,7 +203,10 @@ public bool Ping()
174203
return true;
175204
}
176205

177-
public void ChangeDatabase(string databaseName) { }
206+
public void ChangeDatabase(string databaseName)
207+
{
208+
if (_changeDatabaseThrows) throw new AseException("ChangeDatabase exception");
209+
}
178210
public string Database { get; }
179211
public string DataSource { get; }
180212
public string ServerVersion { get; }

0 commit comments

Comments
 (0)