/// <summary> /// Txn processes multiple requests in a single transaction in async. /// A txn request increments the revision of the key-value store /// and generates events with the same revision for every completed request. /// It is not allowed to modify the same key several times within one txn. /// </summary> /// <param name="request"></param> /// <returns></returns> public async Task <TxnResponse> TransactionAsync(TxnRequest request, Metadata headers = null) { TxnResponse response = new TxnResponse(); bool success = false; int retryCount = 0; while (!success) { try { response = await _balancer.GetConnection().kvClient.TxnAsync(request, headers); success = true; } catch (RpcException ex) when(ex.StatusCode == StatusCode.Unavailable) { retryCount++; if (retryCount >= _balancer._numNodes) { throw ex; } } } return(response); }
/// <summary> /// Txn processes multiple requests in a single transaction in async. /// A txn request increments the revision of the key-value store /// and generates events with the same revision for every completed request. /// It is not allowed to modify the same key several times within one txn. /// </summary> /// <param name="request">The request to send to the server.</param> /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param> /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param> /// <param name="cancellationToken">An optional token for canceling the call.</param> /// <returns>The response received from the server.</returns> public async Task <TxnResponse> TransactionAsync(TxnRequest request, Grpc.Core.Metadata headers = null, DateTime?deadline = null, CancellationToken cancellationToken = default) { TxnResponse response = new TxnResponse(); bool success = false; int retryCount = 0; while (!success) { try { response = await _balancer.GetConnection().kvClient .TxnAsync(request, headers, deadline, cancellationToken); success = true; } catch (RpcException ex) when(ex.StatusCode == StatusCode.Unavailable) { retryCount++; if (retryCount >= _balancer._numNodes) { throw; } } } return(response); }
public void Transaction() { Mock <IEtcdClient> etcdClientMock = new Mock <IEtcdClient>(); Mock <IDisposable> disposableMock = new Mock <IDisposable>(); EtcdCompoundClient client = new EtcdCompoundClient(etcdClientMock.Object, disposableMock.Object); Fixture fixture = new Fixture(); TxnRequest txnRequest = fixture.Create <TxnRequest>(); TxnResponse response = fixture.Create <TxnResponse>(); etcdClientMock.Setup(p => p.Transaction(txnRequest, null, null, CancellationToken.None)).Returns(response); TxnResponse actualResponse = client.Transaction(txnRequest); etcdClientMock.Verify(p => p.Transaction(txnRequest, null, null, CancellationToken.None), Times.Once); Assert.AreSame(response, actualResponse); }