Skip to content

Commit a5a1f62

Browse files
committed
Merge master into netstandard2.0.
Conflicts: src/MySqlConnector/MySqlConnector.csproj tests/SideBySide/SideBySide.csproj
2 parents f5a0848 + 6e4d61b commit a5a1f62

24 files changed

+190
-87
lines changed

.ci/config/config.buffer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
"PasswordlessUser": "no_password",
55
"SecondaryDatabase": "testdb2",
66
"SupportedFeatures": "Json,StoredProcedures,Sha256Password,LargePackets",
7+
8+
"TestData": "../../../../TestData",
79
"MySqlBulkLoaderLocalCsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.CSV",
810
"MySqlBulkLoaderLocalTsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.TSV"
911
}

.ci/config/config.compression+ssl.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
"PasswordlessUser": "no_password",
55
"SecondaryDatabase": "testdb2",
66
"SupportedFeatures": "Json,StoredProcedures,Sha256Password,LargePackets",
7+
8+
"TestData": "../../../../TestData",
79
"MySqlBulkLoaderLocalCsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.CSV",
8-
"MySqlBulkLoaderLocalTsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.TSV"
10+
"MySqlBulkLoaderLocalTsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.TSV",
11+
12+
"CertificatesPath": "../../../../../.ci/server/certs"
913
}
1014
}

.ci/config/config.compression.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
"PasswordlessUser": "no_password",
55
"SecondaryDatabase": "testdb2",
66
"SupportedFeatures": "Json,StoredProcedures,Sha256Password,LargePackets",
7+
8+
"TestData": "../../../../TestData",
79
"MySqlBulkLoaderLocalCsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.CSV",
810
"MySqlBulkLoaderLocalTsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.TSV"
911
}

.ci/config/config.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
"PasswordlessUser": "no_password",
55
"SecondaryDatabase": "testdb2",
66
"SupportedFeatures": "Json,StoredProcedures,Sha256Password,LargePackets",
7+
8+
"TestData": "../../../../TestData",
79
"MySqlBulkLoaderLocalCsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.CSV",
810
"MySqlBulkLoaderLocalTsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.TSV"
911
}

.ci/config/config.ssl.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
"PasswordlessUser": "no_password",
55
"SecondaryDatabase": "testdb2",
66
"SupportedFeatures": "Json,StoredProcedures,Sha256Password,LargePackets",
7+
8+
"TestData": "../../../../TestData",
79
"MySqlBulkLoaderLocalCsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.CSV",
8-
"MySqlBulkLoaderLocalTsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.TSV"
10+
"MySqlBulkLoaderLocalTsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.TSV",
11+
12+
"CertificatesPath": "../../../../../.ci/server/certs"
913
}
1014
}

.ci/config/config.uds+ssl.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
"PasswordlessUser": "no_password",
55
"SecondaryDatabase": "testdb2",
66
"SupportedFeatures": "Json,StoredProcedures,Sha256Password,LargePackets",
7+
8+
"TestData": "../../../../TestData",
79
"MySqlBulkLoaderLocalCsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.CSV",
8-
"MySqlBulkLoaderLocalTsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.TSV"
10+
"MySqlBulkLoaderLocalTsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.TSV",
11+
12+
"CertificatesPath": "../../../../../.ci/server/certs"
913
}
1014
}

.ci/config/config.uds.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
"PasswordlessUser": "no_password",
55
"SecondaryDatabase": "testdb2",
66
"SupportedFeatures": "Json,StoredProcedures,Sha256Password,LargePackets",
7+
8+
"TestData": "../../../../TestData",
79
"MySqlBulkLoaderLocalCsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.CSV",
810
"MySqlBulkLoaderLocalTsvFile": "%TESTDATA%/LoadData_UTF8_BOM_Unix.TSV"
911
}

.ci/run-tests.bat

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@echo off
2-
echo Executing tests with No Compression, No SSL && copy /y tests\SideBySide\config.json.example tests\SideBySide\config.json && dotnet test tests/SideBySide --configuration Release
3-
echo Executing tests with Compression, No SSL && copy /y .ci\config\config.compression.json tests\SideBySide\config.json && dotnet test tests/SideBySide --configuration Release
4-
echo Executing tests with No Compression, SSL && copy /y .ci\config\config.ssl.json tests\SideBySide\config.json && dotnet test tests/SideBySide --configuration Release
5-
echo Executing tests with Compression, SSL && copy /y ".ci\config\config.compression+ssl.json" tests\SideBySide\config.json && dotnet test tests/SideBySide --configuration Release
2+
echo Executing tests with No Compression, No SSL && copy /y .ci\config\config.json tests\SideBySide\config.json && dotnet test tests/SideBySide/SideBySide.csproj --configuration Release
3+
echo Executing tests with Compression, No SSL && copy /y .ci\config\config.compression.json tests\SideBySide\config.json && dotnet test tests/SideBySide/SideBySide.csproj --configuration Release
4+
echo Executing tests with No Compression, SSL && copy /y .ci\config\config.ssl.json tests\SideBySide\config.json && dotnet test tests/SideBySide/SideBySide.csproj --configuration Release
5+
echo Executing tests with Compression, SSL && copy /y ".ci\config\config.compression+ssl.json" tests\SideBySide\config.json && dotnet test tests/SideBySide/SideBySide.csproj --configuration Release

docs/content/overview/version-history.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,20 @@ weight: 30
1111
Version History
1212
===============
1313

14+
### 0.23.0
15+
16+
* Support .NET 4.5: [#295](https://github.com/mysql-net/MySqlConnector/issues/295).
17+
* Send client connection attributes: [#293](https://github.com/mysql-net/MySqlConnector/issues/293).
18+
* Dispose `X509Certificate2` objects (.NET 4.6 and later): [#275](https://github.com/mysql-net/MySqlConnector/issues/275).
19+
20+
### 0.22.0
21+
22+
* Add server certificate validation via `MySqlConnectionStringBuilder.CACertificateFile`: [#280](https://github.com/mysql-net/MySqlConnector/pull/280).
23+
* Support `sha256_password` authentication: [#281](https://github.com/mysql-net/MySqlConnector/issues/281).
24+
* Ignore `IOException` in `TryPingAsync`: [#289](https://github.com/mysql-net/MySqlConnector/issues/289).
25+
* Fix "Aborted connection" server errors when `MySqlConnection` isn't disposed: [#290](https://github.com/mysql-net/MySqlConnector/issues/290).
26+
* Run integration tests on MySQL Server 5.6, MySQL Server 5.7, MariaDB 10.3, Percona Server 5.7.
27+
1428
### 0.21.0
1529

1630
* Add `MySqlHelper.EscapeString`: [#277](https://github.com/mysql-net/MySqlConnector/issues/277).

src/MySqlConnector/MySqlClient/ConnectionPool.cs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace MySql.Data.MySqlClient
1010
{
1111
internal sealed class ConnectionPool
1212
{
13-
public async Task<MySqlSession> GetSessionAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
13+
public async Task<MySqlSession> GetSessionAsync(MySqlConnection connection, IOBehavior ioBehavior, CancellationToken cancellationToken)
1414
{
1515
cancellationToken.ThrowIfCancellationRequested();
1616

@@ -54,17 +54,19 @@ public async Task<MySqlSession> GetSessionAsync(IOBehavior ioBehavior, Cancellat
5454
}
5555

5656
// pooled session is ready to be used; return it
57+
session.OwningConnection = new WeakReference<MySqlConnection>(connection);
5758
lock (m_leasedSessions)
58-
m_leasedSessions.Add(session.Id, new WeakReference<MySqlSession>(session));
59+
m_leasedSessions.Add(session.Id, session);
5960
return session;
6061
}
6162
}
6263

6364
// create a new session
6465
session = new MySqlSession(this, m_generation, Interlocked.Increment(ref m_lastId));
6566
await session.ConnectAsync(m_connectionSettings, ioBehavior, cancellationToken).ConfigureAwait(false);
67+
session.OwningConnection = new WeakReference<MySqlConnection>(connection);
6668
lock (m_leasedSessions)
67-
m_leasedSessions.Add(session.Id, new WeakReference<MySqlSession>(session));
69+
m_leasedSessions.Add(session.Id, session);
6870
return session;
6971
}
7072
catch
@@ -95,6 +97,7 @@ public void Return(MySqlSession session)
9597
{
9698
lock (m_leasedSessions)
9799
m_leasedSessions.Remove(session.Id);
100+
session.OwningConnection = null;
98101
if (SessionIsHealthy(session))
99102
lock (m_sessions)
100103
m_sessions.AddFirst(session);
@@ -111,6 +114,7 @@ public async Task ClearAsync(IOBehavior ioBehavior, CancellationToken cancellati
111114
{
112115
// increment the generation of the connection pool
113116
Interlocked.Increment(ref m_generation);
117+
RecoverLeakedSessions();
114118
await CleanPoolAsync(ioBehavior, session => session.PoolGeneration != m_generation, false, cancellationToken).ConfigureAwait(false);
115119
}
116120

@@ -123,27 +127,25 @@ public async Task ReapAsync(IOBehavior ioBehavior, CancellationToken cancellatio
123127
}
124128

125129
/// <summary>
126-
/// Examines all the <see cref="WeakReference{MySqlSession}"/> in <see cref="m_leasedSessions"/> to determine if any
127-
/// <see cref="MySqlSession"/> objects have been garbage-collected. If so, assumes that the related <see cref="MySqlConnection"/>
128-
/// was not properly disposed but the associated server connection has been closed (by the finalizer). Releases the semaphore
129-
/// once for each leaked session to allow new client connections to be made.
130+
/// Examines all the <see cref="MySqlSession"/> objects in <see cref="m_leasedSessions"/> to determine if any
131+
/// have an owning <see cref="MySqlConnection"/> that has been garbage-collected. If so, assumes that the connection
132+
/// was not properly disposed and returns the session to the pool.
130133
/// </summary>
131134
private void RecoverLeakedSessions()
132135
{
133-
var recoveredIds = new List<int>();
136+
var recoveredSessions = new List<MySqlSession>();
134137
lock (m_leasedSessions)
135138
{
136139
m_lastRecoveryTime = unchecked((uint) Environment.TickCount);
137140
foreach (var pair in m_leasedSessions)
138141
{
139-
if (!pair.Value.TryGetTarget(out var _))
140-
recoveredIds.Add(pair.Key);
142+
var session = pair.Value;
143+
if (!session.OwningConnection.TryGetTarget(out var _))
144+
recoveredSessions.Add(session);
141145
}
142-
foreach (var id in recoveredIds)
143-
m_leasedSessions.Remove(id);
144146
}
145-
if (recoveredIds.Count > 0)
146-
m_sessionSemaphore.Release(recoveredIds.Count);
147+
foreach (var session in recoveredSessions)
148+
session.ReturnToPool();
147149
}
148150

149151
private async Task CleanPoolAsync(IOBehavior ioBehavior, Func<MySqlSession, bool> shouldCleanFn, bool respectMinPoolSize, CancellationToken cancellationToken)
@@ -250,7 +252,7 @@ private ConnectionPool(ConnectionSettings cs)
250252
m_cleanSemaphore = new SemaphoreSlim(1);
251253
m_sessionSemaphore = new SemaphoreSlim(cs.MaximumPoolSize);
252254
m_sessions = new LinkedList<MySqlSession>();
253-
m_leasedSessions = new Dictionary<int, WeakReference<MySqlSession>>();
255+
m_leasedSessions = new Dictionary<int, MySqlSession>();
254256
}
255257

256258
static readonly ConcurrentDictionary<string, ConnectionPool> s_pools = new ConcurrentDictionary<string, ConnectionPool>();
@@ -280,7 +282,7 @@ private ConnectionPool(ConnectionSettings cs)
280282
readonly SemaphoreSlim m_sessionSemaphore;
281283
readonly LinkedList<MySqlSession> m_sessions;
282284
readonly ConnectionSettings m_connectionSettings;
283-
readonly Dictionary<int, WeakReference<MySqlSession>> m_leasedSessions;
285+
readonly Dictionary<int, MySqlSession> m_leasedSessions;
284286
int m_lastId;
285287
uint m_lastRecoveryTime;
286288
}

0 commit comments

Comments
 (0)