private async Task <MyCatSession> CreateSessionAsync(IOBehavior ioBehavior, CancellationToken cancellationToken) { var connectTimeout = m_connectionSettings.ConnectionTimeout == 0 ? Timeout.InfiniteTimeSpan : TimeSpan.FromSeconds(checked ((int)m_connectionSettings.ConnectionTimeout)); using (var timeoutSource = new CancellationTokenSource(connectTimeout)) using (var linkedSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutSource.Token)) { try { // get existing session from the pool if possible if (m_connectionSettings.Pooling) { var pool = ConnectionPool.GetPool(m_connectionSettings); // this returns an open session return(await pool.GetSessionAsync(ioBehavior, linkedSource.Token).ConfigureAwait(false)); } else { var session = new MyCatSession(); await session.ConnectAsync(m_connectionSettings, ioBehavior, linkedSource.Token).ConfigureAwait(false); return(session); } } catch (OperationCanceledException ex) when(timeoutSource.IsCancellationRequested) { throw new MyCatException("Connect Timeout expired.", ex); } } }
public async Task <MyCatSession> GetSessionAsync(IOBehavior ioBehavior, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // wait for an open slot if (ioBehavior == IOBehavior.Asynchronous) { await m_sessionSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); } else { m_sessionSemaphore.Wait(cancellationToken); } try { MyCatSession session; // check for a pooled session if (m_sessions.TryDequeue(out session)) { if (session.PoolGeneration != m_generation || !await session.TryPingAsync(ioBehavior, cancellationToken).ConfigureAwait(false)) { // session is either old or cannot communicate with the server await session.DisposeAsync(ioBehavior, cancellationToken).ConfigureAwait(false); } else { // session is valid, reset if supported if (m_connectionSettings.ConnectionReset) { await session.ResetConnectionAsync(m_connectionSettings, ioBehavior, cancellationToken).ConfigureAwait(false); } // pooled session is ready to be used; return it return(session); } } session = new MyCatSession(this, m_generation); await session.ConnectAsync(m_connectionSettings, ioBehavior, cancellationToken).ConfigureAwait(false); return(session); } catch { m_sessionSemaphore.Release(); throw; } }
public void Return(MyCatSession session) { try { if (session.PoolGeneration == m_generation) { m_sessions.Enqueue(session); } else { session.DisposeAsync(IOBehavior.Synchronous, CancellationToken.None).ConfigureAwait(false); } } finally { m_sessionSemaphore.Release(); } }