Example usage for java.util.concurrent.atomic AtomicBoolean compareAndSet

List of usage examples for java.util.concurrent.atomic AtomicBoolean compareAndSet

Introduction

In this page you can find the example usage for java.util.concurrent.atomic AtomicBoolean compareAndSet.

Prototype

public final boolean compareAndSet(boolean expectedValue, boolean newValue) 

Source Link

Document

Atomically sets the value to newValue if the current value == expectedValue , with memory effects as specified by VarHandle#compareAndSet .

Usage

From source file:io.pravega.segmentstore.server.containers.StreamSegmentMapperTests.java

/**
 * Tests the ability of getOrAssignStreamSegmentId to handle the TooManyActiveSegmentsException.
 *//* w w w  .  j a va 2  s  . c  o m*/
@Test
public void testGetOrAssignStreamSegmentIdWithMetadataLimit() throws Exception {
    final String segmentName = "Segment";
    final String transactionName = StreamSegmentNameUtils.getTransactionNameFromId(segmentName,
            UUID.randomUUID());

    HashSet<String> storageSegments = new HashSet<>();
    storageSegments.add(segmentName);
    storageSegments.add(transactionName);

    @Cleanup
    TestContext context = new TestContext();
    setupStorageGetHandler(context, storageSegments,
            name -> new StreamSegmentInformation(name, 0, false, false, new ImmutableDate()));

    // 1. Verify the behavior when even after the retry we still cannot map.
    AtomicInteger exceptionCounter = new AtomicInteger();
    AtomicBoolean cleanupInvoked = new AtomicBoolean();

    // We use 'containerId' as a proxy for the exception id (to make sure we collect the right one).
    context.operationLog.addHandler = op -> FutureHelpers
            .failedFuture(new TooManyActiveSegmentsException(exceptionCounter.incrementAndGet(), 0));
    Supplier<CompletableFuture<Void>> noOpCleanup = () -> {
        if (!cleanupInvoked.compareAndSet(false, true)) {
            return FutureHelpers.failedFuture(new AssertionError("Cleanup invoked multiple times/"));
        }
        return CompletableFuture.completedFuture(null);
    };
    val mapper1 = new StreamSegmentMapper(context.metadata, context.operationLog, context.stateStore,
            noOpCleanup, context.storage, executorService());
    AssertExtensions.assertThrows(
            "Unexpected outcome when trying to map a segment name to a full metadata that cannot be cleaned.",
            () -> mapper1.getOrAssignStreamSegmentId(segmentName, TIMEOUT),
            ex -> ex instanceof TooManyActiveSegmentsException
                    && ((TooManyActiveSegmentsException) ex).getContainerId() == exceptionCounter.get());
    Assert.assertEquals("Unexpected number of attempts to map.", 2, exceptionCounter.get());
    Assert.assertTrue("Cleanup was not invoked.", cleanupInvoked.get());

    // Now with a transaction.
    exceptionCounter.set(0);
    cleanupInvoked.set(false);
    AssertExtensions.assertThrows(
            "Unexpected outcome when trying to map a segment name to a full metadata that cannot be cleaned.",
            () -> mapper1.getOrAssignStreamSegmentId(transactionName, TIMEOUT),
            ex -> ex instanceof TooManyActiveSegmentsException
                    && ((TooManyActiveSegmentsException) ex).getContainerId() == exceptionCounter.get());
    Assert.assertEquals("Unexpected number of attempts to map.", 2, exceptionCounter.get());
    Assert.assertTrue("Cleanup was not invoked.", cleanupInvoked.get());

    // 2. Verify the behavior when the first call fails, but the second one succeeds.
    exceptionCounter.set(0);
    cleanupInvoked.set(false);
    Supplier<CompletableFuture<Void>> workingCleanup = () -> {
        if (!cleanupInvoked.compareAndSet(false, true)) {
            return FutureHelpers.failedFuture(new AssertionError("Cleanup invoked multiple times."));
        }

        setupOperationLog(context); // Setup the OperationLog to function correctly.
        return CompletableFuture.completedFuture(null);
    };

    val mapper2 = new StreamSegmentMapper(context.metadata, context.operationLog, context.stateStore,
            workingCleanup, context.storage, executorService());
    long id = mapper2.getOrAssignStreamSegmentId(segmentName, TIMEOUT).join();
    Assert.assertEquals("Unexpected number of attempts to map.", 1, exceptionCounter.get());
    Assert.assertTrue("Cleanup was not invoked.", cleanupInvoked.get());
    Assert.assertNotEquals("No valid SegmentId assigned.", ContainerMetadata.NO_STREAM_SEGMENT_ID, id);
}

From source file:org.apache.cassandra.repair.RepairRunnable.java

protected void runMayThrow() throws Exception {
    final TraceState traceState;

    final String tag = "repair:" + cmd;

    final AtomicInteger progress = new AtomicInteger();
    final int totalProgress = 3 + options.getRanges().size(); // calculate neighbors, validation, prepare for repair + number of ranges to repair

    String[] columnFamilies = options.getColumnFamilies()
            .toArray(new String[options.getColumnFamilies().size()]);
    Iterable<ColumnFamilyStore> validColumnFamilies = storageService.getValidColumnFamilies(false, false,
            keyspace, columnFamilies);/*  w  w w .jav a  2s .  c o m*/

    final long startTime = System.currentTimeMillis();
    String message = String.format("Starting repair command #%d, repairing keyspace %s with %s", cmd, keyspace,
            options);
    logger.info(message);
    fireProgressEvent(tag, new ProgressEvent(ProgressEventType.START, 0, 100, message));
    if (options.isTraced()) {
        StringBuilder cfsb = new StringBuilder();
        for (ColumnFamilyStore cfs : validColumnFamilies)
            cfsb.append(", ").append(cfs.keyspace.getName()).append(".").append(cfs.name);

        UUID sessionId = Tracing.instance.newSession(Tracing.TraceType.REPAIR);
        traceState = Tracing.instance.begin("repair",
                ImmutableMap.of("keyspace", keyspace, "columnFamilies", cfsb.substring(2)));
        Tracing.traceRepair(message);
        traceState.enableActivityNotification(tag);
        for (ProgressListener listener : listeners)
            traceState.addProgressListener(listener);
        Thread queryThread = createQueryThread(cmd, sessionId);
        queryThread.setName("RepairTracePolling");
        queryThread.start();
    } else {
        traceState = null;
    }

    final Set<InetAddress> allNeighbors = new HashSet<>();
    Map<Range, Set<InetAddress>> rangeToNeighbors = new HashMap<>();
    try {
        for (Range<Token> range : options.getRanges()) {
            Set<InetAddress> neighbors = ActiveRepairService.getNeighbors(keyspace, range,
                    options.getDataCenters(), options.getHosts());
            rangeToNeighbors.put(range, neighbors);
            allNeighbors.addAll(neighbors);
        }
        progress.incrementAndGet();
    } catch (IllegalArgumentException e) {
        logger.error("Repair failed:", e);
        fireErrorAndComplete(tag, progress.get(), totalProgress, e.getMessage());
        return;
    }

    // Validate columnfamilies
    List<ColumnFamilyStore> columnFamilyStores = new ArrayList<>();
    try {
        Iterables.addAll(columnFamilyStores, validColumnFamilies);
        progress.incrementAndGet();
    } catch (IllegalArgumentException e) {
        fireErrorAndComplete(tag, progress.get(), totalProgress, e.getMessage());
        return;
    }

    String[] cfnames = new String[columnFamilyStores.size()];
    for (int i = 0; i < columnFamilyStores.size(); i++) {
        cfnames[i] = columnFamilyStores.get(i).name;
    }

    final UUID parentSession = UUIDGen.getTimeUUID();
    SystemDistributedKeyspace.startParentRepair(parentSession, keyspace, cfnames, options.getRanges());
    long repairedAt;
    try {
        ActiveRepairService.instance.prepareForRepair(parentSession, allNeighbors, options, columnFamilyStores);
        repairedAt = ActiveRepairService.instance.getParentRepairSession(parentSession).getRepairedAt();
        progress.incrementAndGet();
    } catch (Throwable t) {
        SystemDistributedKeyspace.failParentRepair(parentSession, t);
        fireErrorAndComplete(tag, progress.get(), totalProgress, t.getMessage());
        return;
    }

    // Set up RepairJob executor for this repair command.
    final ListeningExecutorService executor = MoreExecutors.listeningDecorator(
            new JMXConfigurableThreadPoolExecutor(options.getJobThreads(), Integer.MAX_VALUE, TimeUnit.SECONDS,
                    new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("Repair#" + cmd), "internal"));

    List<ListenableFuture<RepairSessionResult>> futures = new ArrayList<>(options.getRanges().size());
    for (Range<Token> range : options.getRanges()) {
        final RepairSession session = ActiveRepairService.instance.submitRepairSession(parentSession, range,
                keyspace, options.getParallelism(), rangeToNeighbors.get(range), repairedAt, executor, cfnames);
        if (session == null)
            continue;
        // After repair session completes, notify client its result
        Futures.addCallback(session, new FutureCallback<RepairSessionResult>() {
            public void onSuccess(RepairSessionResult result) {
                String message = String.format("Repair session %s for range %s finished", session.getId(),
                        session.getRange().toString());
                logger.info(message);
                fireProgressEvent(tag, new ProgressEvent(ProgressEventType.PROGRESS, progress.incrementAndGet(),
                        totalProgress, message));
            }

            public void onFailure(Throwable t) {
                String message = String.format("Repair session %s for range %s failed with error %s",
                        session.getId(), session.getRange().toString(), t.getMessage());
                logger.error(message, t);
                fireProgressEvent(tag, new ProgressEvent(ProgressEventType.PROGRESS, progress.incrementAndGet(),
                        totalProgress, message));
            }
        });
        futures.add(session);
    }

    // After all repair sessions completes(successful or not),
    // run anticompaction if necessary and send finish notice back to client
    final Collection<Range<Token>> successfulRanges = new ArrayList<>();
    final AtomicBoolean hasFailure = new AtomicBoolean();
    final ListenableFuture<List<RepairSessionResult>> allSessions = Futures.successfulAsList(futures);
    ListenableFuture anticompactionResult = Futures.transform(allSessions,
            new AsyncFunction<List<RepairSessionResult>, Object>() {
                @SuppressWarnings("unchecked")
                public ListenableFuture apply(List<RepairSessionResult> results) throws Exception {
                    // filter out null(=failed) results and get successful ranges
                    for (RepairSessionResult sessionResult : results) {
                        if (sessionResult != null) {
                            successfulRanges.add(sessionResult.range);
                        } else {
                            hasFailure.compareAndSet(false, true);
                        }
                    }
                    return ActiveRepairService.instance.finishParentSession(parentSession, allNeighbors,
                            successfulRanges);
                }
            });
    Futures.addCallback(anticompactionResult, new FutureCallback<Object>() {
        public void onSuccess(Object result) {
            SystemDistributedKeyspace.successfulParentRepair(parentSession, successfulRanges);
            if (hasFailure.get()) {
                fireProgressEvent(tag, new ProgressEvent(ProgressEventType.ERROR, progress.get(), totalProgress,
                        "Some repair failed"));
            } else {
                fireProgressEvent(tag, new ProgressEvent(ProgressEventType.SUCCESS, progress.get(),
                        totalProgress, "Repair completed successfully"));
            }
            repairComplete();
        }

        public void onFailure(Throwable t) {
            fireProgressEvent(tag,
                    new ProgressEvent(ProgressEventType.ERROR, progress.get(), totalProgress, t.getMessage()));
            SystemDistributedKeyspace.failParentRepair(parentSession, t);
            repairComplete();
        }

        private void repairComplete() {
            String duration = DurationFormatUtils.formatDurationWords(System.currentTimeMillis() - startTime,
                    true, true);
            String message = String.format("Repair command #%d finished in %s", cmd, duration);
            fireProgressEvent(tag,
                    new ProgressEvent(ProgressEventType.COMPLETE, progress.get(), totalProgress, message));
            logger.info(message);
            if (options.isTraced() && traceState != null) {
                for (ProgressListener listener : listeners)
                    traceState.removeProgressListener(listener);
                // Because DebuggableThreadPoolExecutor#afterExecute and this callback
                // run in a nondeterministic order (within the same thread), the
                // TraceState may have been nulled out at this point. The TraceState
                // should be traceState, so just set it without bothering to check if it
                // actually was nulled out.
                Tracing.instance.set(traceState);
                Tracing.traceRepair(message);
                Tracing.instance.stopSession();
            }
            executor.shutdownNow();
        }
    });
}

From source file:io.atomix.protocols.gossip.map.AntiEntropyMapDelegate.java

/**
 * Requests all updates from each peer in the provided list of peers.
 * <p>/*from   w  ww  . java 2s  .  c  om*/
 * The returned future will be completed once at least one peer bootstraps this map or bootstrap requests to all peers
 * fail.
 *
 * @param peers the list of peers from which to request updates
 * @return a future to be completed once updates have been received from at least one peer
 */
private CompletableFuture<Void> requestBootstrapFromPeers(List<MemberId> peers) {
    if (peers.isEmpty()) {
        return CompletableFuture.completedFuture(null);
    }
    CompletableFuture<Void> future = new CompletableFuture<>();
    final int totalPeers = peers.size();
    AtomicBoolean successful = new AtomicBoolean();
    AtomicInteger totalCount = new AtomicInteger();
    AtomicReference<Throwable> lastError = new AtomicReference<>();

    // Iterate through all of the peers and send a bootstrap request. On the first peer that returns
    // a successful bootstrap response, complete the future. Otherwise, if no peers respond with any
    // successful bootstrap response, the future will be completed with the last exception.
    for (MemberId peer : peers) {
        requestBootstrapFromPeer(peer).whenComplete((result, error) -> {
            if (error == null) {
                if (successful.compareAndSet(false, true)) {
                    future.complete(null);
                } else if (totalCount.incrementAndGet() == totalPeers) {
                    Throwable e = lastError.get();
                    if (e != null) {
                        future.completeExceptionally(e);
                    }
                }
            } else {
                if (!successful.get() && totalCount.incrementAndGet() == totalPeers) {
                    future.completeExceptionally(error);
                } else {
                    lastError.set(error);
                }
            }
        });
    }
    return future;
}

From source file:org.elasticsearch.client.sniff.SnifferTests.java

/**
 * Test behaviour when a bunch of onFailure sniffing rounds are triggered in parallel. Each run will always
 * schedule a subsequent afterFailure round. Also, for each onFailure round that starts, the net scheduled round
 * (either afterFailure or ordinary) gets cancelled.
 *///  w  w  w  .  ja v  a2s.co  m
public void testSniffOnFailure() throws Exception {
    RestClient restClient = mock(RestClient.class);
    CountingHostsSniffer hostsSniffer = new CountingHostsSniffer();
    final AtomicBoolean initializing = new AtomicBoolean(true);
    final long sniffInterval = randomLongBetween(1, Long.MAX_VALUE);
    final long sniffAfterFailureDelay = randomLongBetween(1, Long.MAX_VALUE);
    int minNumOnFailureRounds = randomIntBetween(5, 10);
    final CountDownLatch initializingLatch = new CountDownLatch(1);
    final Set<Sniffer.ScheduledTask> ordinaryRoundsTasks = new CopyOnWriteArraySet<>();
    final AtomicReference<Future<?>> initializingFuture = new AtomicReference<>();
    final Set<Sniffer.ScheduledTask> onFailureTasks = new CopyOnWriteArraySet<>();
    final Set<Sniffer.ScheduledTask> afterFailureTasks = new CopyOnWriteArraySet<>();
    final AtomicBoolean onFailureCompleted = new AtomicBoolean(false);
    final CountDownLatch completionLatch = new CountDownLatch(1);
    final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
    try {
        Scheduler scheduler = new Scheduler() {
            @Override
            public Future<?> schedule(final Sniffer.Task task, long delayMillis) {
                if (initializing.compareAndSet(true, false)) {
                    assertEquals(0L, delayMillis);
                    Future<?> future = executor.submit(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                task.run();
                            } finally {
                                //we need to make sure that the sniffer is initialized, so the sniffOnFailure
                                //call does what it needs to do. Otherwise nothing happens until initialized.
                                initializingLatch.countDown();
                            }
                        }
                    });
                    assertTrue(initializingFuture.compareAndSet(null, future));
                    return future;
                }
                if (delayMillis == 0L) {
                    Future<?> future = executor.submit(task);
                    onFailureTasks.add(new Sniffer.ScheduledTask(task, future));
                    return future;
                }
                if (delayMillis == sniffAfterFailureDelay) {
                    Future<?> future = scheduleOrSubmit(task);
                    afterFailureTasks.add(new Sniffer.ScheduledTask(task, future));
                    return future;
                }

                assertEquals(sniffInterval, delayMillis);
                assertEquals(sniffInterval, task.nextTaskDelay);

                if (onFailureCompleted.get() && onFailureTasks.size() == afterFailureTasks.size()) {
                    completionLatch.countDown();
                    return mock(Future.class);
                }

                Future<?> future = scheduleOrSubmit(task);
                ordinaryRoundsTasks.add(new Sniffer.ScheduledTask(task, future));
                return future;
            }

            private Future<?> scheduleOrSubmit(Sniffer.Task task) {
                if (randomBoolean()) {
                    return executor.schedule(task, randomLongBetween(0L, 200L), TimeUnit.MILLISECONDS);
                } else {
                    return executor.submit(task);
                }
            }

            @Override
            public void shutdown() {
            }
        };
        final Sniffer sniffer = new Sniffer(restClient, hostsSniffer, scheduler, sniffInterval,
                sniffAfterFailureDelay);
        assertTrue("timeout waiting for sniffer to get initialized",
                initializingLatch.await(1000, TimeUnit.MILLISECONDS));

        ExecutorService onFailureExecutor = Executors.newFixedThreadPool(randomIntBetween(5, 20));
        Set<Future<?>> onFailureFutures = new CopyOnWriteArraySet<>();
        try {
            //with tasks executing quickly one after each other, it is very likely that the onFailure round gets skipped
            //as another round is already running. We retry till enough runs get through as that's what we want to test.
            while (onFailureTasks.size() < minNumOnFailureRounds) {
                onFailureFutures.add(onFailureExecutor.submit(new Runnable() {
                    @Override
                    public void run() {
                        sniffer.sniffOnFailure();
                    }
                }));
            }
            assertThat(onFailureFutures.size(), greaterThanOrEqualTo(minNumOnFailureRounds));
            for (Future<?> onFailureFuture : onFailureFutures) {
                assertNull(onFailureFuture.get());
            }
            onFailureCompleted.set(true);
        } finally {
            onFailureExecutor.shutdown();
            onFailureExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS);
        }

        assertFalse(initializingFuture.get().isCancelled());
        assertTrue(initializingFuture.get().isDone());
        assertNull(initializingFuture.get().get());

        assertTrue("timeout waiting for sniffing rounds to be completed",
                completionLatch.await(1000, TimeUnit.MILLISECONDS));
        assertThat(onFailureTasks.size(), greaterThanOrEqualTo(minNumOnFailureRounds));
        assertEquals(onFailureTasks.size(), afterFailureTasks.size());

        for (Sniffer.ScheduledTask onFailureTask : onFailureTasks) {
            assertFalse(onFailureTask.future.isCancelled());
            assertTrue(onFailureTask.future.isDone());
            assertNull(onFailureTask.future.get());
            assertTrue(onFailureTask.task.hasStarted());
            assertFalse(onFailureTask.task.isSkipped());
        }

        int cancelledTasks = 0;
        int completedTasks = onFailureTasks.size() + 1;
        for (Sniffer.ScheduledTask afterFailureTask : afterFailureTasks) {
            if (assertTaskCancelledOrCompleted(afterFailureTask)) {
                completedTasks++;
            } else {
                cancelledTasks++;
            }
        }

        assertThat(ordinaryRoundsTasks.size(), greaterThan(0));
        for (Sniffer.ScheduledTask task : ordinaryRoundsTasks) {
            if (assertTaskCancelledOrCompleted(task)) {
                completedTasks++;
            } else {
                cancelledTasks++;
            }
        }
        assertEquals(onFailureTasks.size(), cancelledTasks);

        assertEquals(completedTasks, hostsSniffer.runs.get());
        int setHostsRuns = hostsSniffer.runs.get() - hostsSniffer.failures.get() - hostsSniffer.emptyList.get();
        verify(restClient, times(setHostsRuns)).setHosts(Matchers.<HttpHost>anyVararg());
        verifyNoMoreInteractions(restClient);
    } finally {
        executor.shutdown();
        executor.awaitTermination(1000L, TimeUnit.MILLISECONDS);
    }
}

From source file:voldemort.store.routed.ThreadPoolRoutedStore.java

@Override
public boolean delete(final ByteArray key, final Version version) throws VoldemortException {
    StoreUtils.assertValidKey(key);/*w ww .  jav  a2  s.  com*/
    final List<Node> nodes = availableNodes(routingStrategy.routeRequest(key.get()));

    // quickly fail if there aren't enough live nodes to meet the
    // requirements
    final int numNodes = nodes.size();
    if (numNodes < this.storeDef.getRequiredWrites())
        throw new InsufficientOperationalNodesException("Only " + numNodes + " nodes in preference list, but "
                + this.storeDef.getRequiredWrites() + " writes required.");

    // A count of the number of successful operations
    final AtomicInteger successes = new AtomicInteger(0);
    final AtomicBoolean deletedSomething = new AtomicBoolean(false);
    // A list of thrown exceptions, indicating the number of failures
    final List<Exception> failures = Collections.synchronizedList(new LinkedList<Exception>());

    // A semaphore indicating the number of completed operations
    // Once inititialized all permits are acquired, after that
    // permits are released when an operation is completed.
    // semaphore.acquire(n) waits for n operations to complete
    final Semaphore semaphore = new Semaphore(0, false);
    // Add the operations to the pool
    for (final Node node : nodes) {
        this.executor.execute(new Runnable() {

            @Override
            public void run() {
                long startNs = System.nanoTime();
                try {
                    boolean deleted = innerStores.get(node.getId()).delete(key, version);
                    successes.incrementAndGet();
                    deletedSomething.compareAndSet(false, deleted);
                    recordSuccess(node, startNs);
                } catch (UnreachableStoreException e) {
                    failures.add(e);
                    recordException(node, startNs, e);
                } catch (VoldemortApplicationException e) {
                    throw e;
                } catch (Exception e) {
                    failures.add(e);
                    logger.warn("Error in DELETE on node " + node.getId() + "(" + node.getHost() + ")", e);
                } finally {
                    // signal that the operation is complete
                    semaphore.release();
                }
            }
        });
    }

    int attempts = Math.min(storeDef.getPreferredWrites(), numNodes);
    if (this.storeDef.getPreferredWrites() <= 0) {
        return true;
    } else {
        for (int i = 0; i < numNodes; i++) {
            try {
                long timeoutMs = timeoutConfig.getOperationTimeout(VoldemortOpCode.DELETE_OP_CODE);
                boolean acquired = semaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS);
                if (!acquired)
                    logger.warn("Delete operation timed out waiting for operation " + i
                            + " to complete after waiting " + timeoutMs + " ms.");
                // okay, at least the required number of operations have
                // completed, were they successful?
                if (successes.get() >= attempts)
                    return deletedSomething.get();
            } catch (InterruptedException e) {
                throw new InsufficientOperationalNodesException("Delete operation interrupted!", e);
            }
        }
    }

    // If we get to here, that means we couldn't hit the preferred number
    // of writes, throw an exception if you can't even hit the required
    // number
    if (successes.get() < storeDef.getRequiredWrites())
        throw new InsufficientOperationalNodesException(
                this.storeDef.getRequiredWrites() + " deletes required, but " + successes.get() + " succeeded.",
                failures);
    else
        return deletedSomething.get();
}

From source file:voldemort.store.routed.RoutedStore.java

public boolean delete(final ByteArray key, final Version version) throws VoldemortException {
    StoreUtils.assertValidKey(key);/*from  w  ww. java 2s . c o  m*/
    final List<Node> nodes = availableNodes(routingStrategy.routeRequest(key.get()));

    // quickly fail if there aren't enough live nodes to meet the
    // requirements
    final int numNodes = nodes.size();
    if (numNodes < this.storeDef.getRequiredWrites())
        throw new InsufficientOperationalNodesException("Only " + numNodes + " nodes in preference list, but "
                + this.storeDef.getRequiredWrites() + " writes required.");

    // A count of the number of successful operations
    final AtomicInteger successes = new AtomicInteger(0);
    final AtomicBoolean deletedSomething = new AtomicBoolean(false);
    // A list of thrown exceptions, indicating the number of failures
    final List<Exception> failures = Collections.synchronizedList(new LinkedList<Exception>());

    // A semaphore indicating the number of completed operations
    // Once inititialized all permits are acquired, after that
    // permits are released when an operation is completed.
    // semaphore.acquire(n) waits for n operations to complete
    final Semaphore semaphore = new Semaphore(0, false);
    // Add the operations to the pool
    for (final Node node : nodes) {
        this.executor.execute(new Runnable() {

            public void run() {
                long startNs = System.nanoTime();
                try {
                    boolean deleted = innerStores.get(node.getId()).delete(key, version);
                    successes.incrementAndGet();
                    deletedSomething.compareAndSet(false, deleted);
                    recordSuccess(node, startNs);
                } catch (UnreachableStoreException e) {
                    failures.add(e);
                    recordException(node, startNs, e);
                } catch (VoldemortApplicationException e) {
                    throw e;
                } catch (Exception e) {
                    failures.add(e);
                    logger.warn("Error in DELETE on node " + node.getId() + "(" + node.getHost() + ")", e);
                } finally {
                    // signal that the operation is complete
                    semaphore.release();
                }
            }
        });
    }

    int attempts = Math.min(storeDef.getPreferredWrites(), numNodes);
    if (this.storeDef.getPreferredWrites() <= 0) {
        return true;
    } else {
        for (int i = 0; i < numNodes; i++) {
            try {
                boolean acquired = semaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS);
                if (!acquired)
                    logger.warn("Delete operation timed out waiting for operation " + i
                            + " to complete after waiting " + timeoutMs + " ms.");
                // okay, at least the required number of operations have
                // completed, were they successful?
                if (successes.get() >= attempts)
                    return deletedSomething.get();
            } catch (InterruptedException e) {
                throw new InsufficientOperationalNodesException("Delete operation interrupted!", e);
            }
        }
    }

    // If we get to here, that means we couldn't hit the preferred number
    // of writes, throw an exception if you can't even hit the required
    // number
    if (successes.get() < storeDef.getRequiredWrites())
        throw new InsufficientOperationalNodesException(
                this.storeDef.getRequiredWrites() + " deletes required, but " + successes.get() + " succeeded.",
                failures);
    else
        return deletedSomething.get();
}

From source file:com.vmware.admiral.adapter.docker.service.DockerAdapterService.java

private void connectCreatedContainerToNetworks(RequestContext context) {
    AtomicInteger count = new AtomicInteger(context.containerState.networks.size());
    AtomicBoolean error = new AtomicBoolean();

    for (Entry<String, ServiceNetwork> entry : context.containerState.networks.entrySet()) {

        CommandInput connectCommandInput = new CommandInput(context.commandInput);

        String containerId = context.containerState.id;
        String networkId = entry.getKey();

        addNetworkConfig(connectCommandInput, context.containerState.id, entry.getKey(), entry.getValue());

        context.executor.connectContainerToNetwork(connectCommandInput, (o, ex) -> {
            if (ex != null) {
                logWarning("Exception while connecting container [%s] to network [%s]", containerId, networkId);
                if (error.compareAndSet(false, true)) {
                    // Update the container state so further actions (e.g. cleanup) can be performed
                    context.containerState.status = ContainerState.CONTAINER_ERROR_STATUS;
                    context.containerState.powerState = ContainerState.PowerState.ERROR;
                    context.requestFailed = true;
                    inspectContainer(context);

                    fail(context.request, o, ex);
                }//ww w. ja  v a2  s  . c om
            } else if (count.decrementAndGet() == 0) {
                startCreatedContainer(context);
            }
        });
    }
}

From source file:org.apache.nifi.web.api.ProcessGroupResource.java

/**
 * Instantiates the specified template within this ProcessGroup. The template instance that is instantiated cannot be referenced at a later time, therefore there is no
 * corresponding URI. Instead the request URI is returned.
 * <p>/*from  w w w.  j  a  va  2 s  .c o m*/
 * Alternatively, we could have performed a PUT request. However, PUT requests are supposed to be idempotent and this endpoint is certainly not.
 *
 * @param httpServletRequest               request
 * @param groupId                          The group id
 * @param requestInstantiateTemplateRequestEntity The instantiate template request
 * @return A flowEntity.
 */
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("{id}/template-instance")
@ApiOperation(value = "Instantiates a template", response = FlowEntity.class, authorizations = {
        @Authorization(value = "Write - /process-groups/{uuid}", type = ""),
        @Authorization(value = "Read - /templates/{uuid}", type = ""),
        @Authorization(value = "Write - if the template contains any restricted components - /restricted-components", type = "") })
@ApiResponses(value = {
        @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
        @ApiResponse(code = 401, message = "Client could not be authenticated."),
        @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
        @ApiResponse(code = 404, message = "The specified resource could not be found."),
        @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") })
public Response instantiateTemplate(@Context HttpServletRequest httpServletRequest,
        @ApiParam(value = "The process group id.", required = true) @PathParam("id") String groupId,
        @ApiParam(value = "The instantiate template request.", required = true) InstantiateTemplateRequestEntity requestInstantiateTemplateRequestEntity) {

    // ensure the position has been specified
    if (requestInstantiateTemplateRequestEntity == null
            || requestInstantiateTemplateRequestEntity.getOriginX() == null
            || requestInstantiateTemplateRequestEntity.getOriginY() == null) {
        throw new IllegalArgumentException("The  origin position (x, y) must be specified");
    }

    if (isReplicateRequest()) {
        return replicate(HttpMethod.POST, requestInstantiateTemplateRequestEntity);
    }

    return withWriteLock(serviceFacade, requestInstantiateTemplateRequestEntity, lookup -> {
        final NiFiUser user = NiFiUserUtils.getNiFiUser();

        // ensure write on the group
        final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
        processGroup.authorize(authorizer, RequestAction.WRITE, user);

        // ensure read on the template
        final TemplateAuthorizable template = lookup
                .getTemplate(requestInstantiateTemplateRequestEntity.getTemplateId());
        template.getAuthorizable().authorize(authorizer, RequestAction.READ, user);

        // flag to only perform the restricted check once, atomic reference so we can mark final and use in lambda
        final AtomicBoolean restrictedCheckPerformed = new AtomicBoolean(false);
        final Consumer<ConfigurableComponentAuthorizable> authorizeRestricted = authorizable -> {
            if (authorizable.isRestricted() && restrictedCheckPerformed.compareAndSet(false, true)) {
                lookup.getRestrictedComponents().authorize(authorizer, RequestAction.WRITE, user);
            }
        };

        // ensure restricted access if necessary
        template.getEncapsulatedProcessors().forEach(authorizeRestricted);
        template.getEncapsulatedControllerServices().forEach(authorizeRestricted);
    }, null, instantiateTemplateRequestEntity -> {
        // create the template and generate the json
        final FlowEntity entity = serviceFacade.createTemplateInstance(groupId,
                instantiateTemplateRequestEntity.getOriginX(), instantiateTemplateRequestEntity.getOriginY(),
                instantiateTemplateRequestEntity.getTemplateId(), getIdGenerationSeed().orElse(null));

        final FlowDTO flowSnippet = entity.getFlow();

        // prune response as necessary
        for (ProcessGroupEntity childGroupEntity : flowSnippet.getProcessGroups()) {
            childGroupEntity.getComponent().setContents(null);
        }

        // create the response entity
        populateRemainingSnippetContent(flowSnippet);

        // generate the response
        return clusterContext(generateCreatedResponse(getAbsolutePath(), entity)).build();
    });
}

From source file:org.apache.nifi.web.api.ProcessGroupResource.java

/**
 * Copies the specified snippet within this ProcessGroup. The snippet instance that is instantiated cannot be referenced at a later time, therefore there is no
 * corresponding URI. Instead the request URI is returned.
 * <p>//from w  w w.  j a v a2  s  .  c om
 * Alternatively, we could have performed a PUT request. However, PUT requests are supposed to be idempotent and this endpoint is certainly not.
 *
 * @param httpServletRequest request
 * @param groupId            The group id
 * @param requestCopySnippetEntity  The copy snippet request
 * @return A flowSnippetEntity.
 */
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("{id}/snippet-instance")
@ApiOperation(value = "Copies a snippet and discards it.", response = FlowSnippetEntity.class, authorizations = {
        @Authorization(value = "Write - /process-groups/{uuid}", type = ""),
        @Authorization(value = "Read - /{component-type}/{uuid} - For each component in the snippet and their descendant components", type = ""),
        @Authorization(value = "Write - if the snippet contains any restricted Processors - /restricted-components", type = "") })
@ApiResponses(value = {
        @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
        @ApiResponse(code = 401, message = "Client could not be authenticated."),
        @ApiResponse(code = 403, message = "Client is not authorized to make this request."),
        @ApiResponse(code = 404, message = "The specified resource could not be found."),
        @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") })
public Response copySnippet(@Context HttpServletRequest httpServletRequest,
        @ApiParam(value = "The process group id.", required = true) @PathParam("id") String groupId,
        @ApiParam(value = "The copy snippet request.", required = true) CopySnippetRequestEntity requestCopySnippetEntity) {

    // ensure the position has been specified
    if (requestCopySnippetEntity == null || requestCopySnippetEntity.getOriginX() == null
            || requestCopySnippetEntity.getOriginY() == null) {
        throw new IllegalArgumentException("The  origin position (x, y) must be specified");
    }

    if (requestCopySnippetEntity.getSnippetId() == null) {
        throw new IllegalArgumentException("The snippet id must be specified.");
    }

    if (isReplicateRequest()) {
        return replicate(HttpMethod.POST, requestCopySnippetEntity);
    }

    return withWriteLock(serviceFacade, requestCopySnippetEntity, lookup -> {
        final NiFiUser user = NiFiUserUtils.getNiFiUser();
        final SnippetAuthorizable snippet = authorizeSnippetUsage(lookup, groupId,
                requestCopySnippetEntity.getSnippetId(), false);

        // flag to only perform the restricted check once, atomic reference so we can mark final and use in lambda
        final AtomicBoolean restrictedCheckPerformed = new AtomicBoolean(false);
        final Consumer<ConfigurableComponentAuthorizable> authorizeRestricted = authorizable -> {
            if (authorizable.isRestricted() && restrictedCheckPerformed.compareAndSet(false, true)) {
                lookup.getRestrictedComponents().authorize(authorizer, RequestAction.WRITE, user);
            }
        };

        // consider each processor. note - this request will not create new controller services so we do not need to check
        // for if there are not restricted controller services. it will however, need to authorize the user has access
        // to any referenced services and this is done within authorizeSnippetUsage above.
        snippet.getSelectedProcessors().stream().forEach(authorizeRestricted);
        snippet.getSelectedProcessGroups().stream().forEach(processGroup -> {
            processGroup.getEncapsulatedProcessors().forEach(authorizeRestricted);
        });
    }, null, copySnippetRequestEntity -> {
        // copy the specified snippet
        final FlowEntity flowEntity = serviceFacade.copySnippet(groupId,
                copySnippetRequestEntity.getSnippetId(), copySnippetRequestEntity.getOriginX(),
                copySnippetRequestEntity.getOriginY(), getIdGenerationSeed().orElse(null));

        // get the snippet
        final FlowDTO flow = flowEntity.getFlow();

        // prune response as necessary
        for (ProcessGroupEntity childGroupEntity : flow.getProcessGroups()) {
            childGroupEntity.getComponent().setContents(null);
        }

        // create the response entity
        populateRemainingSnippetContent(flow);

        // generate the response
        return clusterContext(generateCreatedResponse(getAbsolutePath(), flowEntity)).build();
    });
}

From source file:org.thoughtcrime.securesms.conversation.ConversationActivity.java

private ListenableFuture<Boolean> initializeDraftFromDatabase() {
    SettableFuture<Boolean> future = new SettableFuture<>();

    new AsyncTask<Void, Void, List<Draft>>() {
        @Override//from   w  w w  . ja v a  2 s  .co  m
        protected List<Draft> doInBackground(Void... params) {
            DraftDatabase draftDatabase = DatabaseFactory.getDraftDatabase(ConversationActivity.this);
            List<Draft> results = draftDatabase.getDrafts(threadId);

            draftDatabase.clearDrafts(threadId);

            return results;
        }

        @Override
        protected void onPostExecute(List<Draft> drafts) {
            if (drafts.isEmpty()) {
                future.set(false);
                updateToggleButtonState();
                return;
            }

            AtomicInteger draftsRemaining = new AtomicInteger(drafts.size());
            AtomicBoolean success = new AtomicBoolean(false);
            ListenableFuture.Listener<Boolean> listener = new AssertedSuccessListener<Boolean>() {
                @Override
                public void onSuccess(Boolean result) {
                    success.compareAndSet(false, result);

                    if (draftsRemaining.decrementAndGet() <= 0) {
                        future.set(success.get());
                    }
                }
            };

            for (Draft draft : drafts) {
                try {
                    switch (draft.getType()) {
                    case Draft.TEXT:
                        composeText.setText(draft.getValue());
                        listener.onSuccess(true);
                        break;
                    case Draft.LOCATION:
                        attachmentManager.setLocation(SignalPlace.deserialize(draft.getValue()),
                                getCurrentMediaConstraints()).addListener(listener);
                        break;
                    case Draft.IMAGE:
                        setMedia(Uri.parse(draft.getValue()), MediaType.IMAGE).addListener(listener);
                        break;
                    case Draft.AUDIO:
                        setMedia(Uri.parse(draft.getValue()), MediaType.AUDIO).addListener(listener);
                        break;
                    case Draft.VIDEO:
                        setMedia(Uri.parse(draft.getValue()), MediaType.VIDEO).addListener(listener);
                        break;
                    case Draft.QUOTE:
                        SettableFuture<Boolean> quoteResult = new SettableFuture<>();
                        new QuoteRestorationTask(draft.getValue(), quoteResult).execute();
                        quoteResult.addListener(listener);
                        break;
                    }
                } catch (IOException e) {
                    Log.w(TAG, e);
                }
            }

            updateToggleButtonState();
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

    return future;
}