@Override public PingTxnStatus pingTxn(final String scope, final String stream, final UUID txnId, Version version, long lease) { if (!this.isRunning()) { return PingTxnStatus.newBuilder().setStatus(PingTxnStatus.Status.DISCONNECTED).build(); } final String key = getKey(scope, stream, txnId); Preconditions.checkState(map.containsKey(key), "Stream not found in the map"); final TxnData txnData = map.get(key); if (txnData == null) { throw new IllegalStateException(String.format("Transaction %s not added to timerWheelTimeoutService", txnId)); } if (lease > maxLeaseValue) { return PingTxnStatus.newBuilder().setStatus(PingTxnStatus.Status.LEASE_TOO_LARGE).build(); } if (lease + System.currentTimeMillis() > txnData.getMaxExecutionTimeExpiry()) { return PingTxnStatus.newBuilder().setStatus(PingTxnStatus.Status.MAX_EXECUTION_TIME_EXCEEDED).build(); } else { Timeout timeout = txnData.getTimeout(); boolean cancelSucceeded = timeout.cancel(); if (cancelSucceeded) { TxnData newTxnData = txnData.updateLease(scope, stream, txnId, version, lease); map.replace(key, txnData, newTxnData); return PingTxnStatus.newBuilder().setStatus(PingTxnStatus.Status.OK).build(); } else { // Cancellation may fail because timeout task (1) may be scheduled for execution, or (2) is executing. throw new IllegalStateException(String.format("Failed updating timeout for transaction %s", txnId)); } } }
@java.lang.Override public int hashCode() { if (memoizedHashCode != 0) { return memoizedHashCode; } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); hash = (37 * hash) + STATUS_FIELD_NUMBER; hash = (53 * hash) + status_; hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; }
@Test(timeout = 10000) public void testControllerPingFailureDisconnected() throws InterruptedException { TxnId txnId = controllerService.createTransaction(SCOPE, STREAM, LEASE) .thenApply(x -> ModelHelper.decode(x.getKey())) .join(); Optional<Throwable> result = timeoutService.getTaskCompletionQueue().poll((long) (0.75 * LEASE), TimeUnit.MILLISECONDS); Assert.assertNull(result); TxnState status = controllerService.checkTransactionStatus(SCOPE, STREAM, txnId).join(); Assert.assertEquals(TxnState.State.OPEN, status.getState()); // Stop timeoutService, and then try pinging the transaction. timeoutService.stopAsync(); PingTxnStatus pingStatus = controllerService.pingTransaction(SCOPE, STREAM, txnId, LEASE).join(); Assert.assertEquals(PingTxnStatus.Status.DISCONNECTED, pingStatus.getStatus()); result = timeoutService.getTaskCompletionQueue().poll((long) (0.5 * LEASE), TimeUnit.MILLISECONDS); Assert.assertNull(result); // Check that the transaction status is still open, since timeoutService has been stopped. status = controllerService.checkTransactionStatus(SCOPE, STREAM, txnId).join(); Assert.assertEquals(TxnState.State.OPEN, status.getState()); }
Assert.assertEquals(0, tx3.getVersion().asIntVersion().getIntValue()); Assert.assertEquals(1, tx4get.getVersion().asIntVersion().getIntValue()); Assert.assertEquals(PingTxnStatus.Status.OK, pingStatus.getStatus());
Assert.assertEquals(PingTxnStatus.Status.OK, pingStatus.getStatus());
@io.grpc.stub.annotations.RpcMethod( fullMethodName = SERVICE_NAME + '/' + "pingTransaction", requestType = io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnRequest.class, responseType = io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnStatus.class, methodType = io.grpc.MethodDescriptor.MethodType.UNARY) public static io.grpc.MethodDescriptor<io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnRequest, io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnStatus> getPingTransactionMethod() { io.grpc.MethodDescriptor<io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnRequest, io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnStatus> getPingTransactionMethod; if ((getPingTransactionMethod = ControllerServiceGrpc.getPingTransactionMethod) == null) { synchronized (ControllerServiceGrpc.class) { if ((getPingTransactionMethod = ControllerServiceGrpc.getPingTransactionMethod) == null) { ControllerServiceGrpc.getPingTransactionMethod = getPingTransactionMethod = io.grpc.MethodDescriptor.<io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnRequest, io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnStatus>newBuilder() .setType(io.grpc.MethodDescriptor.MethodType.UNARY) .setFullMethodName(generateFullMethodName( "io.pravega.controller.stream.api.grpc.v1.ControllerService", "pingTransaction")) .setSampledToLocalTracing(true) .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnRequest.getDefaultInstance())) .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnStatus.getDefaultInstance())) .setSchemaDescriptor(new ControllerServiceMethodDescriptorSupplier("pingTransaction")) .build(); } } } return getPingTransactionMethod; }
@Override public CompletableFuture<Void> pingTransaction(Stream stream, UUID txId, long lease) { Exceptions.checkNotClosed(closed.get(), this); long traceId = LoggerHelpers.traceEnter(log, "pingTransaction", stream, txId, lease); final CompletableFuture<PingTxnStatus> result = this.retryConfig.runAsync(() -> { RPCAsyncCallback<PingTxnStatus> callback = new RPCAsyncCallback<>(traceId, "pingTransaction"); client.pingTransaction(PingTxnRequest.newBuilder().setStreamInfo( ModelHelper.createStreamInfo(stream.getScope(), stream.getStreamName())) .setTxnId(ModelHelper.decode(txId)) .setLease(lease).build(), callback); return callback.getFuture(); }, this.executor); return Futures.toVoidExpecting(result, PingTxnStatus.newBuilder().setStatus(PingTxnStatus.Status.OK).build(), PingFailedException::new) .whenComplete((x, e) -> { if (e != null) { log.warn("pingTransaction failed: ", e); } LoggerHelpers.traceLeave(log, "pingTransaction", traceId); }); }
@Test(timeout = 10000) public void testPingSuccess() throws InterruptedException { UUID txnId = streamStore.generateTransactionId(SCOPE, STREAM, null, executor).join(); VersionedTransactionData txData = streamStore.createTransaction(SCOPE, STREAM, txnId, LEASE, 10 * LEASE, null, executor).join(); timeoutService.addTxn(SCOPE, STREAM, txData.getId(), txData.getVersion(), LEASE, txData.getMaxExecutionExpiryTime()); Optional<Throwable> result = timeoutService.getTaskCompletionQueue().poll((long) (0.75 * LEASE), TimeUnit.MILLISECONDS); Assert.assertNull(result); TxnStatus status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join(); Assert.assertEquals(TxnStatus.OPEN, status); PingTxnStatus pingStatus = timeoutService.pingTxn(SCOPE, STREAM, txData.getId(), txData.getVersion(), LEASE); Assert.assertEquals(PingTxnStatus.Status.OK, pingStatus.getStatus()); result = timeoutService.getTaskCompletionQueue().poll((long) (0.5 * LEASE), TimeUnit.MILLISECONDS); Assert.assertNull(result); status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join(); Assert.assertEquals(TxnStatus.OPEN, status); result = timeoutService.getTaskCompletionQueue().poll((long) (0.8 * LEASE), TimeUnit.MILLISECONDS); Assert.assertNotNull(result); status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join(); Assert.assertEquals(TxnStatus.ABORTING, status); }
@Test(timeout = 10000) public void testPingFailureDisconnected() throws InterruptedException { UUID txnId = streamStore.generateTransactionId(SCOPE, STREAM, null, executor).join(); VersionedTransactionData txData = streamStore.createTransaction(SCOPE, STREAM, txnId, LEASE, 10 * LEASE, null, executor).join(); timeoutService.addTxn(SCOPE, STREAM, txData.getId(), txData.getVersion(), LEASE, txData.getMaxExecutionExpiryTime()); Optional<Throwable> result = timeoutService.getTaskCompletionQueue().poll((long) (0.75 * LEASE), TimeUnit.MILLISECONDS); Assert.assertNull(result); TxnStatus status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join(); Assert.assertEquals(TxnStatus.OPEN, status); // Stop timeoutService, and then try pinging the transaction. timeoutService.stopAsync(); PingTxnStatus pingStatus = timeoutService.pingTxn(SCOPE, STREAM, txData.getId(), txData.getVersion(), LEASE); Assert.assertEquals(PingTxnStatus.Status.DISCONNECTED, pingStatus.getStatus()); result = timeoutService.getTaskCompletionQueue().poll((long) (0.5 * LEASE), TimeUnit.MILLISECONDS); Assert.assertNull(result); // Check that the transaction status is still open, since timeoutService has been stopped. status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join(); Assert.assertEquals(TxnStatus.OPEN, status); }
@Test(timeout = 10000) public void testControllerPingSuccess() throws InterruptedException { TxnId txnId = controllerService.createTransaction(SCOPE, STREAM, LEASE) .thenApply(x -> ModelHelper.decode(x.getKey())) .join(); Optional<Throwable> result = timeoutService.getTaskCompletionQueue().poll((long) (0.75 * LEASE), TimeUnit.MILLISECONDS); Assert.assertNull(result); TxnState txnState = controllerService.checkTransactionStatus(SCOPE, STREAM, txnId).join(); Assert.assertEquals(TxnState.State.OPEN, txnState.getState()); PingTxnStatus pingStatus = controllerService.pingTransaction(SCOPE, STREAM, txnId, LEASE).join(); Assert.assertEquals(PingTxnStatus.Status.OK, pingStatus.getStatus()); result = timeoutService.getTaskCompletionQueue().poll((long) (0.5 * LEASE), TimeUnit.MILLISECONDS); Assert.assertNull(result); txnState = controllerService.checkTransactionStatus(SCOPE, STREAM, txnId).join(); Assert.assertEquals(TxnState.State.OPEN, txnState.getState()); result = timeoutService.getTaskCompletionQueue().poll((long) (0.8 * LEASE), TimeUnit.MILLISECONDS); Assert.assertNotNull(result); txnState = controllerService.checkTransactionStatus(SCOPE, STREAM, txnId).join(); Assert.assertEquals(TxnState.State.ABORTING, txnState.getState()); }
@Test(timeout = 10000) public void testControllerPingLeaseTooLarge() { int lease = 10; TxnId txnId = controllerService.createTransaction(SCOPE, STREAM, lease) .thenApply(x -> ModelHelper.decode(x.getKey())) .join(); PingTxnStatus pingStatus = controllerService.pingTransaction(SCOPE, STREAM, txnId, Config.MAX_LEASE_VALUE + 1).join(); Assert.assertEquals(PingTxnStatus.Status.LEASE_TOO_LARGE, pingStatus.getStatus()); pingStatus = controllerService.pingTransaction(SCOPE, STREAM, txnId, 1000 * lease + 1).join(); Assert.assertEquals(PingTxnStatus.Status.MAX_EXECUTION_TIME_EXCEEDED, pingStatus.getStatus()); UUID txnId1 = streamStore.generateTransactionId(SCOPE, STREAM, null, executor).join(); VersionedTransactionData txData = streamStore.createTransaction(SCOPE, STREAM, txnId1, LEASE, 2 * LEASE, null, executor).join(); txnId = ModelHelper.decode(txData.getId()); pingStatus = controllerService.pingTransaction(SCOPE, STREAM, txnId, Config.MAX_LEASE_VALUE + 1).join(); Assert.assertEquals(PingTxnStatus.Status.LEASE_TOO_LARGE, pingStatus.getStatus()); pingStatus = controllerService.pingTransaction(SCOPE, STREAM, txnId, 3 * LEASE).join(); Assert.assertEquals(PingTxnStatus.Status.MAX_EXECUTION_TIME_EXCEEDED, pingStatus.getStatus()); }
@Test(timeout = 10000) public void testPingFailureMaxExecutionTimeExceeded() throws InterruptedException { UUID txnId = streamStore.generateTransactionId(SCOPE, STREAM, null, executor).join(); VersionedTransactionData txData = streamStore.createTransaction(SCOPE, STREAM, txnId, LEASE, 2 * LEASE, null, executor).join(); timeoutService.addTxn(SCOPE, STREAM, txData.getId(), txData.getVersion(), LEASE, txData.getMaxExecutionExpiryTime()); TxnStatus status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join(); Assert.assertEquals(TxnStatus.OPEN, status); // 3 * LEASE > 2 * LEASE PingTxnStatus pingStatus = timeoutService.pingTxn(SCOPE, STREAM, txData.getId(), txData.getVersion(), 3 * LEASE); Assert.assertEquals(PingTxnStatus.Status.MAX_EXECUTION_TIME_EXCEEDED, pingStatus.getStatus()); status = streamStore.transactionStatus(SCOPE, STREAM, txData.getId(), null, executor).join(); Assert.assertEquals(TxnStatus.OPEN, status); }
public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder() {
private PingTxnStatus createStatus(Status status) { return PingTxnStatus.newBuilder().setStatus(status).build(); }
@Override @Synchronized public CompletableFuture<PingTxnStatus> pingTxn(final String scope, final String stream, final UUID txId, final long lease, final OperationContext contextOpt) { final OperationContext context = contextOpt == null ? streamMetadataStore.createContext(scope, stream) : contextOpt; return streamMetadataStore.getTransactionData(scope, stream, txId, context, executor).thenComposeAsync(data -> streamMetadataStore.pingTransaction(scope, stream, data, lease, context, executor) .thenApply(txData -> { log.info("Pinged transaction {} with version {}", txId, txData.getVersion()); return PingTxnStatus.newBuilder().setStatus(Status.OK).build(); })); }
public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() { return io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnStatus.getDescriptor().getEnumTypes().get(0); }
@Test(timeout = 10000) public void testPingLeaseTooLarge() { UUID txnId = streamStore.generateTransactionId(SCOPE, STREAM, null, executor).join(); VersionedTransactionData txData = streamStore.createTransaction(SCOPE, STREAM, txnId, LEASE, 10 * LEASE, null, executor).join(); timeoutService.addTxn(SCOPE, STREAM, txData.getId(), txData.getVersion(), LEASE, txData.getMaxExecutionExpiryTime()); Version version = txData.getVersion(); PingTxnStatus pingStatus = timeoutService.pingTxn(SCOPE, STREAM, txData.getId(), version, Config.MAX_LEASE_VALUE + 1); Assert.assertEquals(PingTxnStatus.Status.LEASE_TOO_LARGE, pingStatus.getStatus()); pingStatus = timeoutService.pingTxn(SCOPE, STREAM, txData.getId(), version, 10 * LEASE + 1); Assert.assertEquals(PingTxnStatus.Status.MAX_EXECUTION_TIME_EXCEEDED, pingStatus.getStatus()); }
@Test(timeout = 10000) public void testControllerPingFailureMaxExecutionTimeExceeded() throws InterruptedException { int lease = 10; TxnId txnId = controllerService.createTransaction(SCOPE, STREAM, lease) .thenApply(x -> ModelHelper.decode(x.getKey())) .join(); TxnState txnState = controllerService.checkTransactionStatus(SCOPE, STREAM, txnId).join(); Assert.assertEquals(TxnState.State.OPEN, txnState.getState()); PingTxnStatus pingStatus = controllerService.pingTransaction(SCOPE, STREAM, txnId, 1000 * lease).join(); Assert.assertEquals(PingTxnStatus.Status.MAX_EXECUTION_TIME_EXCEEDED, pingStatus.getStatus()); txnState = controllerService.checkTransactionStatus(SCOPE, STREAM, txnId).join(); Assert.assertEquals(TxnState.State.OPEN, txnState.getState()); }
public io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnStatus buildPartial() { io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnStatus result = new io.pravega.controller.stream.api.grpc.v1.Controller.PingTxnStatus(this); result.status_ = status_; onBuilt(); return result; }
@Override public void pingTransaction(PingTxnRequest request, StreamObserver<PingTxnStatus> responseObserver) { if (request.getStreamInfo().getStream().equals("stream1")) { responseObserver.onNext(PingTxnStatus.newBuilder().setStatus(PingTxnStatus.Status.OK).build()); responseObserver.onCompleted(); } else { responseObserver.onError(Status.INTERNAL.withDescription("Server error").asRuntimeException()); } }