Exemple #1
0
 private PooledSession(SessionPool.ISessionPool pool, SessionName sessionName, ByteString transactionId, ModeOneofCase transactionMode, DateTime evictionTime, long refreshTicks)
 {
     GaxPreconditions.CheckArgument(
         (transactionId == null) == (transactionMode == ModeOneofCase.None),
         nameof(transactionMode),
         "Transaction mode and ID don't match.");
     _pool           = pool;
     SessionName     = GaxPreconditions.CheckNotNull(sessionName, nameof(sessionName));
     TransactionId   = transactionId;
     TransactionMode = transactionMode;
     _session        = new Session {
         SessionName = SessionName
     };
     _evictionTime = evictionTime;
     _refreshTicks = refreshTicks;
 }
            private Task <PooledSession> GetSessionAcquisitionTask(ModeOneofCase transactionMode, CancellationToken cancellationToken)
            {
                // Three scenarios for initial session picking:
                // - No transaction options: take a read-only session as-is
                // - Read/write transaction options: take a read/write session as-is
                // - Other options (a non-single-use read-only bound, or PDML): take a read-only session, but fetch a transaction with it before returning it.
                // If there's no session of the appropriate type, take the other kind instead - at the cost of either wasting an existing read/write
                // transaction, or having to acquire a read/write transaction.
                ConcurrentQueue <PooledSession> preferredQueue = _readOnlySessions;
                ConcurrentQueue <PooledSession> alternateQueue = _readWriteSessions;

                if (transactionMode == ModeOneofCase.ReadWrite)
                {
                    preferredQueue = _readWriteSessions;
                    alternateQueue = _readOnlySessions;
                }
                lock (_lock)
                {
                    // First try the pool.
                    if (preferredQueue.TryDequeue(out var session) || alternateQueue.TryDequeue(out session))
                    {
                        // Slight inefficiency wrapping this in a task, but it makes the implementation simpler.
                        return(Task.FromResult(session));
                    }

                    // No pool entries.
                    // If the pool is currently healthy, register a TCS in the queue that will be checked by incoming sessions.
                    if (Healthy)
                    {
                        TaskCompletionSource <PooledSession> receivingTcs = new TaskCompletionSource <PooledSession>();
                        _pendingAcquisitions.Enqueue(receivingTcs);
                        return(receivingTcs.WithCancellationToken(cancellationToken));
                    }
                    else
                    {
                        // Otherwise, drop out of the lock to create a session from scratch "inline" (still asynchronously, but not via an in-flight request).
                    }
                }
                // Effectively the "else" block above, but outside the lock
                return(CreatePooledSessionAsync(cancellationToken));
            }
 /// <summary>
 /// Creates a <see cref="PooledSession"/> with a known name and transaction ID/mode, with the client associated
 /// with this pool, but is otherwise not part of this pool. This method does not query the server for the session state.
 /// When the returned <see cref="PooledSession"/> is released, it will not become part of this pool, and the transaction
 /// will not be rolled back.
 /// </summary>
 /// <remarks>
 /// This is typically used for partitioned queries, where the same session is used across multiple machines, so should
 /// not be reused by the pool.
 /// </remarks>
 /// <param name="sessionName">The name of the transaction. Must not be null.</param>
 /// <param name="transactionId">The ID of the transaction. Must not be null.</param>
 /// <param name="transactionMode">The mode of the transaction.</param>
 /// <returns>A <see cref="PooledSession"/> for the given session and transaction.</returns>
 public PooledSession CreateDetachedSession(SessionName sessionName, ByteString transactionId, ModeOneofCase transactionMode)
 {
     GaxPreconditions.CheckNotNull(sessionName, nameof(sessionName));
     GaxPreconditions.CheckNotNull(transactionId, nameof(transactionId));
     return(PooledSession.FromSessionName(_detachedSessionPool, sessionName).WithTransaction(transactionId, transactionMode));
 }
 public void ClearMode()
 {
     modeCase_ = ModeOneofCase.None;
     mode_     = null;
 }
Exemple #5
0
 internal PooledSession WithTransaction(ByteString transactionId, ModeOneofCase transactionMode)
 {
     MarkAsDisposed();
     return(new PooledSession(_pool, SessionName, transactionId, transactionMode, _evictionTime, _refreshTicks));
 }
Exemple #6
0
 /// <summary>
 /// Creates a <see cref="PooledSession"/> with a known name and transaction ID/mode, with the client associated
 /// with this pool, but is otherwise not part of this pool. This method does not query the server for the session state.
 /// When the returned <see cref="PooledSession"/> is released, it will not become part of this pool, and the transaction
 /// will not be rolled back.
 /// </summary>
 /// <remarks>
 /// This is typically used for partitioned queries, where the same session is used across multiple machines, so should
 /// not be reused by the pool.
 /// </remarks>
 /// <param name="sessionName">The name of the transaction. Must not be null.</param>
 /// <param name="transactionId">The ID of the transaction. Must not be null.</param>
 /// <param name="transactionMode">The mode of the transaction.</param>
 /// <returns>A <see cref="PooledSession"/> for the given session and transaction.</returns>
 public PooledSession CreateDetachedSession(SessionName sessionName, ByteString transactionId, ModeOneofCase transactionMode) =>
 CreateDetachedSession(sessionName, transactionId, transactionMode, readTimestamp: null);
Exemple #7
0
 internal PooledSession WithTransaction(ByteString transactionId, ModeOneofCase transactionMode) =>
 new PooledSession(_pool, SessionName, transactionId, transactionMode, _evictionTime, _refreshTicks);