/// <summary> /// Sends a <see cref="IOperation" /> to the Couchbase Server using the Memcached protocol using async/await. /// </summary> /// <param name="operation">The <see cref="IOperation" /> to send.</param> /// <returns> /// An <see cref="Task{IOperationResult}" /> object representing the asynchronous operation. /// </returns> public override Task <IOperationResult> SendWithRetryAsync(IOperation operation) { var tcs = new TaskCompletionSource <IOperationResult>(); var cts = new CancellationTokenSource(OperationLifeSpan); cts.CancelAfter(OperationLifeSpan); try { operation.Completed = CallbackFactory.CompletedFuncWithRetryForMemcached( this, Pending, ClusterController, tcs, cts.Token); Pending.TryAdd(operation.Opaque, operation); var server = GetServer(operation.Key); server.SendAsync(operation).ConfigureAwait(false); } catch (Exception e) { tcs.TrySetResult(new OperationResult { Exception = e, Status = ResponseStatus.ClientFailure }); } return(tcs.Task); }
/// <summary> /// Sends a <see cref="IOperation" /> to the Couchbase Server using the Memcached protocol using async/await. /// </summary> /// <param name="operation">The <see cref="IOperation" /> to send.</param> /// /// <param name="tcs">The <see cref="TaskCompletionSource{T}"/> the represents the task to await on.</param> /// <param name="cts">The <see cref="CancellationTokenSource"/> for cancellation.</param> /// <returns> /// An <see cref="Task{IOperationResult}" /> object representing the asynchronous operation. /// </returns> public override async Task <IOperationResult> SendWithRetryAsync(IOperation operation, TaskCompletionSource <IOperationResult> tcs = null, CancellationTokenSource cts = null) { tcs = tcs ?? new TaskCompletionSource <IOperationResult>(); cts = cts ?? new CancellationTokenSource(OperationLifeSpan); var parentSpan = Tracer.StartParentSpan(operation, ConfigInfo.BucketName); try { operation.Completed = CallbackFactory.CompletedFuncWithRetryForMemcached( this, Pending, ClusterController, tcs, cts.Token); Pending.TryAdd(operation.Opaque, operation); IServer server; var attempts = 0; while ((server = GetServer(operation.Key)) == null) { if (attempts++ > 10) { throw new TimeoutException("Could not acquire a server."); } await Task.Delay((int)Math.Pow(2, attempts)).ContinueOnAnyContext(); } await server.SendAsync(operation).ContinueOnAnyContext(); } catch (Exception e) { tcs.TrySetResult(new OperationResult { Id = operation.Key, Exception = e, Status = ResponseStatus.ClientFailure }); } finally { parentSpan.Finish(); } return(await tcs.Task.ContinueOnAnyContext()); }
/// <summary> /// Sends a <see cref="IOperation" /> to the Couchbase Server using the Memcached protocol using async/await. /// </summary> /// <param name="operation">The <see cref="IOperation" /> to send.</param> /// /// <param name="tcs">The <see cref="TaskCompletionSource{T}"/> the represents the task to await on.</param> /// <param name="cts">The <see cref="CancellationTokenSource"/> for cancellation.</param> /// <returns> /// An <see cref="Task{IOperationResult}" /> object representing the asynchronous operation. /// </returns> public override Task <IOperationResult> SendWithRetryAsync(IOperation operation, TaskCompletionSource <IOperationResult> tcs = null, CancellationTokenSource cts = null) { tcs = tcs ?? new TaskCompletionSource <IOperationResult>(); cts = cts ?? new CancellationTokenSource(OperationLifeSpan); try { operation.Completed = CallbackFactory.CompletedFuncWithRetryForMemcached( this, Pending, ClusterController, tcs, cts.Token); Pending.TryAdd(operation.Opaque, operation); IServer server; var attempts = 0; while ((server = GetServer(operation.Key)) == null) { if (attempts++ > 10) { throw new TimeoutException("Could not acquire a server."); } Thread.Sleep((int)Math.Pow(2, attempts)); } server.SendAsync(operation).ConfigureAwait(false); } catch (Exception e) { tcs.TrySetResult(new OperationResult { Id = operation.Key, Exception = e, Status = ResponseStatus.ClientFailure }); } return(tcs.Task); }