Ado.Netプロバイダを提供するIn memoryデータベースExasol
を使用していますが、重要な機能の一部が表示されていないようです(ConnectionPooling
)。すべての接続が作成され、破棄されます。リクエストは、AWS
というホストされたデータベースに接続しているため、パフォーマンスに影響しています。私は簡単なConnectionPool
を作成して、Resize
の能力を持っています。これが目的を果たすかどうか、あるいはもっと何かをする必要があるかどうかをお勧めします。Exasol Ado.Netプロバイダ用のカスタム接続プール
私は現在の実装で欠落している可能性のあるものについて、また再利用できる実装がある場合(Nuget、Git)のコードレビューを探しているわけではありません。現在、私はサイズに基づいてサイズを変更していますが、時間に基づいてどのように同じ時間を達成するかは、待ち時間から特定の期間を空けて、キューからリソースを少なくし、サイズを減らします。
重要な詳細:
- 使用
ConcurrentQueue
内部リソースへのスレッドセーフなアクセスのために、複数のクライアントからの - 使用
AutoResetEvent
待機し、信号用プールが操作をリサイズするために 使用
TPL
空の場合は、呼び出し元のコードを停止することなく、クライアント呼び出しが返されても、私の理解はこの作業です。Threadpool thread
class ExasolConnectionPool { /// <summary> /// Thread safe queue for storing the connection objects /// </summary> private ConcurrentQueue<EXAConnection> ExasolConnectionQueue { get; set; } /// <summary> /// Number of connections on the Connection pool /// </summary> private int _connectionCount; /// <summary> /// Max Pool Size /// </summary> private int MaxPoolSize { get; set; } /// <summary> /// Min Pool Size /// </summary> private int MinPoolSize { get; set; } /// <summary> /// Increase in Pool Size /// </summary> private int IncreasePoolSize { get; set; } /// <summary> /// Decrease in Pool Size /// </summary> private int DecreasePoolSize { get; set; } /// <summary> /// Connection string for the Connection pool connections /// </summary> private string ConnectionString { get; set; } /// <summary> /// Auto Reset event for the connection pool /// </summary> private AutoResetEvent ExasolConnectionPoolAre { get; set; } /// <summary> /// Connection pool specific Lock object /// </summary> private readonly object lockObject; /// <summary> /// Connection pool constructor /// </summary> /// <param name="connectionString"></param> /// <param name="poolSize"></param> public ExasolConnectionPool(string connectionString, int poolSize = 10) { // Set the Connection String ConnectionString = connectionString; // Intialize the Connection Queue ExasolConnectionQueue = new ConcurrentQueue<EXAConnection>(); // Enqueue initial set of connections for (int counter = 0; counter < poolSize; counter++) { var exaConnection = new EXAConnection {ConnectionString = ConnectionString}; ExasolConnectionQueue.Enqueue(exaConnection); } // Initialize Lock object lockObject = new object(); // Set the Connection queue count _connectionCount = poolSize; // Max pool size MaxPoolSize = poolSize; // Min Pool Size MinPoolSize = 2; IncreasePoolSize = 5; DecreasePoolSize = 3; ExasolConnectionPoolAre = new AutoResetEvent(false); } /// <summary> /// /// </summary> /// <returns></returns> public EXAConnection GetConnection() { // Return ExaConnection object EXAConnection returnConnection; // Try Dequeue the connection object from the Concurrent Queue var validExasolConnection = ExasolConnectionQueue.TryDequeue(out returnConnection); // If No Valid connection is available, then wait using AutoReset signaling mechanism while (!validExasolConnection) { ExasolConnectionPoolAre.WaitOne(); validExasolConnection = ExasolConnectionQueue.TryDequeue(out returnConnection); } // Thread safe connection count update Interlocked.Decrement(ref _connectionCount); Task.Factory.StartNew(() => { lock (lockObject) { if (_connectionCount > MinPoolSize) return; for (var counter = 0; counter < IncreasePoolSize; counter++) { var exaConnection = new EXAConnection {ConnectionString = ConnectionString}; ExasolConnectionQueue.Enqueue(exaConnection); Interlocked.Increment(ref _connectionCount); } } }); return (returnConnection); } /// <summary> /// /// </summary> /// <param name="returnedConnection"></param> public void ReturnConnection(EXAConnection returnedConnection) { ExasolConnectionQueue.Enqueue(returnedConnection); Interlocked.Increment(ref _connectionCount); ExasolConnectionPoolAre.Set(); Task.Factory.StartNew(() => { lock (lockObject) { if (_connectionCount < MaxPoolSize * 1.5) return; for (var counter = 0; counter < DecreasePoolSize; counter++) { EXAConnection exaConnection; if (ExasolConnectionQueue.TryDequeue(out exaConnection)) { exaConnection.Dispose(); exaConnection = null; Interlocked.Decrement(ref _connectionCount); } } } }); } }
お読みいただきありがとうございます。リサイズの場合、接続オブジェクトは高価なリソースであるため、標準的なリソースプールとは異なり、制御されたリサイズメカニズムを優先します。一定期間を超えたアイドル状態の接続は、リソースの無駄です。他のリソースプールでも、必要に応じて作成/追加する必要がある実際のオブジェクトではなく、倍増することによってコレクションのサイズが大きくなります。 –
あなたが気付いたように、それらはプライベートオブジェクトですが、標準接続プールのユーザーと同様に、例外を避けるために特定のチェックを使用して調整することができます。 –
ええ、それは単なる観測でした。私はあなたが何をやっているのか知っていると思うので、あなたのプロジェクトで幸運を祈る:) – VMAtm