/// <summary> /// Initializes a new instance of the <see cref="PooledQldbSession"/> class. /// </summary> /// /// <param name="qldbSession">The QldbSession instance that this wraps.</param> /// <param name="disposeDelegate">The delegate method to invoke upon disposal of this.</param> /// <param name="logger">The logger to be used by this.</param> internal PooledQldbSession(QldbSession qldbSession, Action <QldbSession> disposeDelegate, ILogger logger) { this.session = qldbSession; this.disposeDelegate = disposeDelegate; this.logger = logger; this.isClosed = false; }
/// <summary> /// Execute a function in session pool. /// </summary> /// <typeparam name="T">The return type of the function.</typeparam> /// /// <param name="func">The function to be executed in the session pool. The operation can be cancelled.</param> /// <param name="retryPolicy">The policy on retry.</param> /// <param name="retryAction">The customer retry action. The operation can be cancelled.</param> /// <param name="cancellationToken"> /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. /// </param> /// /// <returns>The result from the function.</returns> public async Task <T> Execute <T>(Func <TransactionExecutor, CancellationToken, Task <T> > func, RetryPolicy retryPolicy, Func <int, CancellationToken, Task> retryAction, CancellationToken cancellationToken = default) { QldbSession session = null; try { session = await this.GetSession(cancellationToken); return(await this.retryHandler.RetriableExecute( ct => session.Execute(func, ct), retryPolicy, async ct => session = await this.StartNewSession(ct), async ct => { this.poolPermits.Release(); session = await this.GetSession(ct); }, retryAction, cancellationToken)); } finally { if (session != null) { session.Release(); } } }
internal T Execute <T>(Func <TransactionExecutor, T> func, RetryPolicy retryPolicy, Action <int> retryAction) { this.driverBase.ThrowIfClosed(); bool replaceDeadSession = false; for (int retryAttempt = 1; true; retryAttempt++) { QldbSession session = null; try { if (replaceDeadSession) { session = this.StartNewSession(); } else { session = this.GetSession(); } T returnedValue = session.Execute(func); this.driverBase.ReleaseSession(session); return(returnedValue); } catch (QldbTransactionException qte) { replaceDeadSession = this.driverBase.GetShouldReplaceDeadSessionOrThrowIfNoRetry( qte, session, retryAttempt, retryPolicy, retryAction); } } }
/// <summary> /// Execute a function in session pool. /// </summary> /// <typeparam name="T">The return type of the function.</typeparam> /// <param name="func">The function to be executed in the session pool.</param> /// <param name="retryPolicy">The policy on retry.</param> /// <param name="retryAction">The customer retry action.</param> /// <returns>The result from the function.</returns> public T Execute <T>(Func <TransactionExecutor, T> func, RetryPolicy retryPolicy, Action <int> retryAction) { QldbSession session = null; try { session = this.GetSession(); return(this.retryHandler.RetriableExecute( () => session.Execute(func), retryPolicy, () => session = this.StartNewSession(), () => { this.poolPermits.Release(); session = this.GetSession(); }, retryAction)); } finally { if (session != null) { session.Release(); } } }
private void ReleaseSession(QldbSession session) { if (session != null && session.IsAlive()) { this.sessionPool.Add(session); } this.poolPermits.Release(); this.logger.LogDebug("Session returned to pool; pool size is now {}.", this.sessionPool.Count); }
private PooledQldbSession WrapSession(QldbSession session) { return(new PooledQldbSession(session, this.ReleaseSession, this.logger)); }