start.set(System.currentTimeMillis()); vertx.setTimer(1000, tid -> { ar.result().release(); }); vertx.executeBlocking(future -> {
@Test public void testReleaseTwice() { waitFor(3); AtomicInteger count = new AtomicInteger(); // success lock count getVertx().sharedData().getLock("foo", onSuccess(lock1 -> { count.incrementAndGet(); complete(); for (int i = 0; i < 2; i++) { getVertx().sharedData().getLockWithTimeout("foo", 10, ar -> { if (ar.succeeded()) { count.incrementAndGet(); } complete(); }); } lock1.release(); lock1.release(); })); await(); assertEquals(2, count.get()); } }
@Test public void testAcquire() { getVertx().sharedData().getLock("foo", ar -> { assertTrue(ar.succeeded()); long start = System.currentTimeMillis(); Lock lock = ar.result(); vertx.setTimer(1000, tid -> { lock.release(); }); getVertx().sharedData().getLock("foo", ar2 -> { assertTrue(ar2.succeeded()); // Should be delayed assertTrue(System.currentTimeMillis() - start >= 1000); testComplete(); }); }); await(); }
@Test public void testAcquireDifferentLocksOnSameEventLoop() { Vertx vertx = getVertx(); Context context = vertx.getOrCreateContext(); SharedData sharedData = vertx.sharedData(); AtomicInteger stage = new AtomicInteger(); context.runOnContext(v -> { sharedData.getLock("foo", onSuccess(foo -> { assertTrue(stage.compareAndSet(0, 1)); // Create another lock request sharedData.getLock("foo", onSuccess(foo1 -> { assertEquals(2, stage.get()); foo1.release(); testComplete(); })); // Should not be blocked by second request for lock "foo" sharedData.getLock("bar", onSuccess(bar -> { assertTrue(stage.compareAndSet(1, 2)); foo.release(); bar.release(); })); })); }); await(); }
@Test public void testAcquireOnSameEventLoop() { Vertx vertx = getVertx(); Context context = vertx.getOrCreateContext(); SharedData sharedData = vertx.sharedData(); AtomicReference<Long> start = new AtomicReference<>(); context.runOnContext(v -> { sharedData.getLock("foo", ar -> { assertTrue(ar.succeeded()); start.set(System.currentTimeMillis()); Lock lock = ar.result(); vertx.setTimer(1000, tid -> { lock.release(); }); context.runOnContext(v2 -> { sharedData.getLock("foo", ar2 -> { assertTrue(ar2.succeeded()); // Should be delayed assertTrue(System.currentTimeMillis() - start.get() >= 1000); testComplete(); }); }); }); }); await(); }
start.set(System.currentTimeMillis()); vertx.setTimer(1000, tid -> { ar.result().release(); }); vertx.executeBlocking(future -> {
/** * Release the lock. Once the lock is released another will be able to obtain the lock. */ public void release() { delegate.release(); }
/** * Release the lock. Once the lock is released another will be able to obtain the lock. */ public void release() { delegate.release(); }
@Test public void testReleaseTwice() { waitFor(3); AtomicInteger count = new AtomicInteger(); // success lock count getVertx().sharedData().getLock("foo", onSuccess(lock1 -> { count.incrementAndGet(); complete(); for (int i = 0; i < 2; i++) { getVertx().sharedData().getLockWithTimeout("foo", 10, ar -> { if (ar.succeeded()) { count.incrementAndGet(); } complete(); }); } lock1.release(); lock1.release(); })); await(); assertEquals(2, count.get()); } }
@Test public void testAcquireDifferentLocksOnSameEventLoop() { Vertx vertx = getVertx(); Context context = vertx.getOrCreateContext(); SharedData sharedData = vertx.sharedData(); AtomicInteger stage = new AtomicInteger(); context.runOnContext(v -> { sharedData.getLock("foo", onSuccess(foo -> { assertTrue(stage.compareAndSet(0, 1)); // Create another lock request sharedData.getLock("foo", onSuccess(foo1 -> { assertEquals(2, stage.get()); foo1.release(); testComplete(); })); // Should not be blocked by second request for lock "foo" sharedData.getLock("bar", onSuccess(bar -> { assertTrue(stage.compareAndSet(1, 2)); foo.release(); bar.release(); })); })); }); await(); }
@Test public void testAcquireOnSameEventLoop() { Vertx vertx = getVertx(); Context context = vertx.getOrCreateContext(); SharedData sharedData = vertx.sharedData(); AtomicReference<Long> start = new AtomicReference<>(); context.runOnContext(v -> { sharedData.getLock("foo", ar -> { assertTrue(ar.succeeded()); start.set(System.currentTimeMillis()); Lock lock = ar.result(); vertx.setTimer(1000, tid -> { lock.release(); }); context.runOnContext(v2 -> { sharedData.getLock("foo", ar2 -> { assertTrue(ar2.succeeded()); // Should be delayed assertTrue(System.currentTimeMillis() - start.get() >= 1000); testComplete(); }); }); }); }); await(); }
@Test public void testAcquire() { getVertx().sharedData().getLock("foo", ar -> { assertTrue(ar.succeeded()); long start = System.currentTimeMillis(); Lock lock = ar.result(); vertx.setTimer(1000, tid -> { lock.release(); }); getVertx().sharedData().getLock("foo", ar2 -> { assertTrue(ar2.succeeded()); // Should be delayed assertTrue(System.currentTimeMillis() - start >= 1000); testComplete(); }); }); await(); }
private static <T> void openCircuitBreakerAndHandleError( Consumer<Throwable> errorHandler, ThrowableErrorConsumer<Throwable, T> onFailureRespond, Consumer<Throwable> errorMethodHandler, Consumer<ExecutionResult<T>> resultConsumer, AsyncResult<T> event, Lock lock, Counter counter) { counter.addAndGet( LOCK_VALUE, val -> { lock.release(); errorHandling( errorHandler, onFailureRespond, errorMethodHandler, resultConsumer, Future.failedFuture(event.cause())); }); }
private static <T> void openCircuitBreakerAndHandleError( Consumer<Throwable> errorHandler, ThrowableErrorConsumer<Throwable, T> onFailureRespond, Consumer<Throwable> errorMethodHandler, Consumer<ExecutionResult<T>> resultConsumer, AsyncResult<T> event, Lock lock, Counter counter) { counter.addAndGet( LOCK_VALUE, val -> { lock.release(); errorHandling( errorHandler, onFailureRespond, errorMethodHandler, resultConsumer, Future.failedFuture(event.cause())); }); }
private static <T> void openCircuitBreakerAndHandleError( Consumer<Throwable> errorHandler, ThrowableErrorConsumer<Throwable, T> onFailureRespond, Consumer<Throwable> errorMethodHandler, Consumer<ExecutionResult<T>> resultConsumer, AsyncResult<T> event, Lock lock, Counter counter) { counter.addAndGet( LOCK_VALUE, val -> { lock.release(); errorHandling( errorHandler, onFailureRespond, errorMethodHandler, resultConsumer, Future.failedFuture(event.cause())); }); }
private static <T> void openCircuitBreakerAndHandleError( Consumer<Throwable> errorHandler, ThrowableErrorConsumer<Throwable, T> onFailureRespond, Consumer<Throwable> errorMethodHandler, Consumer<ExecutionResult<T>> resultConsumer, AsyncResult<T> event, Lock lock, Counter counter) { counter.addAndGet( LOCK_VALUE, val -> { lock.release(); errorHandling( errorHandler, onFailureRespond, errorMethodHandler, resultConsumer, Future.failedFuture(event.cause())); }); }
private void createThisNode() throws Exception { //clean ha node would be happened multi times with multi vertx node in startup, so we have a lock to avoid conflict. this.getLockWithTimeout("__cluster_init_lock", 3000L, lockAsyncResult -> { if (lockAsyncResult.succeeded()) { try { //we have to clear `__vertx.haInfo` node if cluster is empty, as __haInfo is PERSISTENT mode, so we can not delete last //child of this path. if (clusterNodes.getCurrentData().size() == 0 && curator.checkExists().forPath("/syncMap") != null && curator.checkExists().forPath("/syncMap/" + VERTX_HA_NODE) != null) { getSyncMap(VERTX_HA_NODE).clear(); } } catch (Exception ex) { log.error("check zk node failed.", ex); } finally { lockAsyncResult.result().release(); } } else { log.error("get cluster init lock failed.", lockAsyncResult.cause()); } }); curator.create().withMode(CreateMode.EPHEMERAL).forPath(ZK_PATH_CLUSTER_NODE + nodeID, nodeID.getBytes()); }
private static <T> void executeDefaultState( long _timeout, ThrowableFutureConsumer<T> _userOperation, VxmsShared vxmsShared, Future<T> operationResult, Lock lock) { lock.release(); if (_timeout > DEFAULT_LONG_VALUE) { addTimeoutHandler( _timeout, vxmsShared, (l) -> { if (!operationResult.isComplete()) { operationResult.fail(new TimeoutException("operation timeout")); } }); } executeAndCompleate(_userOperation, operationResult); }
private static <T, V> void executeDefaultState( long _timeout, ThrowableFutureBiConsumer<T, V> step, T inputValue, VxmsShared vxmsShared, Future<V> operationResult, Lock lock) { lock.release(); if (_timeout > DEFAULT_LONG_VALUE) { addTimeoutHandler( _timeout, vxmsShared, (l) -> { if (!operationResult.isComplete()) { operationResult.fail(new TimeoutException("operation timeout")); } }); } executeAndCompleate(step, inputValue, operationResult); }
createOrUpdate(reconciliation, cr) .setHandler(createResult -> { lock.release(); log.debug("{}: Lock {} released", reconciliation, lockName); if (createResult.failed()) { log.info("{}: Assembly {} should be deleted", reconciliation, assemblyName); delete(reconciliation).setHandler(deleteResult -> { lock.release(); log.debug("{}: Lock {} released", reconciliation, lockName); if (deleteResult.succeeded()) { lock.release(); log.debug("{}: Lock {} released", reconciliation, lockName); handler.handle(Future.failedFuture(ex));