-
Notifications
You must be signed in to change notification settings - Fork 345
-
Hi,
I use this hack for MySql.Data
to get stats on the connection pool thru reflection.
Totally understanding that this is in no way supported, I still wonder if I could get some pointers on where similar values might exist in MySqlConnector
?
Logic psuedo explained:
- Grab ConnectionPool object using connection string, since that is the unique key
- Pull out Available "pool slots", inUse connections in pool, idle connections in pool
public int[] GetPoolStatsViaReflection() { var asm = typeof(MySqlConnectionStringBuilder).Assembly; var poolManagerType = asm.GetType("MySql.Data.MySqlClient.MySqlPoolManager"); // internal sealed var poolType = asm.GetType("MySql.Data.MySqlClient.MySqlPool"); // internal sealed var pool = poolManagerType.InvokeMember("GetPool", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, null, null, new object[] { this.connectionStringBuilder }); const System.Reflection.BindingFlags nonPublicInstanceField = System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance; var totalAvailable = (int)poolType.InvokeMember("available", nonPublicInstanceField, null, pool, new object[] { }); // List<Driver> var inUsePool = (System.Collections.ICollection)poolType.InvokeMember("inUsePool", nonPublicInstanceField, null, pool, new object[] { }); // Queue<Driver> var idlePool = (System.Collections.ICollection)poolType.InvokeMember("idlePool", nonPublicInstanceField, null, pool, new object[] { }); return new[] {totalAvailable, inUsePool.Count, idlePool.Count}; }
I guess this lives in MySqlConnector.Core.ConnectionPool
and maybe m_leasedSessions
is similar to inUsePool?
Beta Was this translation helpful? Give feedback.
All reactions
MySqlConnector.Core.ConnectionPool.s_pools
will contain all known connection pools:
MySqlConnector.Core.ConnectionPool.m_sessions.Count
has the number of idle (pooled) sessions:
MySqlConnector.Core.ConnectionPool.m_leasedSessions.Count
has the number of active (in-use) sessions:
Replies: 2 comments 1 reply
-
Related: #491
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
MySqlConnector.Core.ConnectionPool.s_pools
will contain all known connection pools:
MySqlConnector.Core.ConnectionPool.m_sessions.Count
has the number of idle (pooled) sessions:
MySqlConnector.Core.ConnectionPool.m_leasedSessions.Count
has the number of active (in-use) sessions:
MySqlConnector.Core.ConnectionPool.ConnectionSettings.MaximumPoolSize
contains the maximum number of active connections that can be created:
I'm sure it goes without saying but this is completely unsupported. Moreover, this is highly concurrent code, and some of these properties are not safe to read when there are concurrent writers.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 2 -
❤️ 1
-
Fantastic, thanks!
I have not yet seen any issue with getting counts without locks (not thinking about getting missmatching values)
Saying it again absolutely unsupported, The usecase is to grab some data on exceptions. So should be rare.
Initial implementation:
var asm = typeof(MySqlConnectionStringBuilder).Assembly; const string MySqlCoreName = "MySqlConnector." + nameof(MySqlConnector.Core); var poolType = asm.GetType(MySqlCoreName + ".ConnectionPool"); // internal sealed var settingType = asm.GetType(MySqlCoreName + ".ConnectionSettings"); // internal sealed var pool = poolType.InvokeMember("GetPool", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, null, null, new object[] { this.connectionStringBuilder.ConnectionString }); const System.Reflection.BindingFlags nonPublicInstanceField = System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance; var settings = poolType.InvokeMember("ConnectionSettings", nonPublicInstanceField | System.Reflection.BindingFlags.GetProperty, null, pool, new object[] { }); var maxPoolSize = (int)settingType.InvokeMember("MaximumPoolSize", nonPublicInstanceField | System.Reflection.BindingFlags.GetProperty, null, settings, new object[] { }); // Dictionary<string, ServerSession> // has the number of active (in-use) sessions: var inUse = (System.Collections.ICollection)poolType.InvokeMember("m_leasedSessions", nonPublicInstanceField, null, pool, new object[] { }); // LinkedList<ServerSession> // has the number of idle (pooled) sessions: var idle = (System.Collections.ICollection)poolType.InvokeMember("m_sessions", nonPublicInstanceField, null, pool, new object[] { }); var inUseCount = inUse.Count; var idleCount = idle.Count; return new[] { maxPoolSize - inUseCount, inUseCount, idleCount };
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1