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

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

Introduction

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

Prototype

public AtomicBoolean(boolean initialValue) 

Source Link

Document

Creates a new AtomicBoolean with the given initial value.

Usage

From source file:info.archinnov.achilles.it.TestTypedQueries.java

@Test
public void should_iterate_regular_typed_query() throws Exception {
    //Given//from ww w .  ja  v  a  2s .c  o  m
    final Map<String, Object> values = new HashMap<>();
    final long id = RandomUtils.nextLong(0L, Long.MAX_VALUE);
    values.put("id", id);
    values.put("date1", "'2015-10-01 00:00:00+0000'");
    values.put("date2", "'2015-10-02 00:00:00+0000'");
    values.put("date3", "'2015-10-03 00:00:00+0000'");
    values.put("date4", "'2015-10-04 00:00:00+0000'");
    values.put("date5", "'2015-10-05 00:00:00+0000'");
    values.put("date6", "'2015-10-06 00:00:00+0000'");
    values.put("date7", "'2015-10-07 00:00:00+0000'");
    values.put("date8", "'2015-10-08 00:00:00+0000'");
    values.put("date9", "'2015-10-09 00:00:00+0000'");
    scriptExecutor.executeScriptTemplate("SimpleEntity/insert_many_rows.cql", values);

    final SimpleStatement statement = new SimpleStatement("SELECT * FROM simple WHERE id = :id LIMIT 100");

    //When
    final Iterator<SimpleEntity> iter = manager.query().typedQueryForSelect(statement, id).iterator();

    //Then
    final AtomicBoolean foundEntity = new AtomicBoolean(false);
    iter.forEachRemaining(instance -> {
        foundEntity.getAndSet(true);
        assertThat(instance).isNotNull();
        assertThat(instance.getValue()).contains("id - date");
    });

    assertThat(foundEntity.get()).isTrue();
}

From source file:it.anyplace.sync.bep.BlockPusher.java

public FileUploadObserver pushFile(final DataSource dataSource, @Nullable FileInfo fileInfo,
        final String folder, final String path) {
    checkArgument(connectionHandler.hasFolder(folder),
            "supplied connection handler %s will not share folder %s", connectionHandler, folder);
    checkArgument(fileInfo == null || equal(fileInfo.getFolder(), folder));
    checkArgument(fileInfo == null || equal(fileInfo.getPath(), path));
    try {/*from w  ww  . j a va 2  s  .c om*/
        final ExecutorService monitoringProcessExecutorService = Executors.newCachedThreadPool();
        final long fileSize = dataSource.getSize();
        final Set<String> sentBlocks = Sets.newConcurrentHashSet();
        final AtomicReference<Exception> uploadError = new AtomicReference<>();
        final AtomicBoolean isCompleted = new AtomicBoolean(false);
        final Object updateLock = new Object();
        final Object listener = new Object() {
            @Subscribe
            public void handleRequestMessageReceivedEvent(RequestMessageReceivedEvent event) {
                BlockExchageProtos.Request request = event.getMessage();
                if (equal(request.getFolder(), folder) && equal(request.getName(), path)) {
                    try {
                        final String hash = BaseEncoding.base16().encode(request.getHash().toByteArray());
                        logger.debug("handling block request = {}:{}-{} ({})", request.getName(),
                                request.getOffset(), request.getSize(), hash);
                        byte[] data = dataSource.getBlock(request.getOffset(), request.getSize(), hash);
                        checkNotNull(data, "data not found for hash = %s", hash);
                        final Future future = connectionHandler.sendMessage(
                                Response.newBuilder().setCode(BlockExchageProtos.ErrorCode.NO_ERROR)
                                        .setData(ByteString.copyFrom(data)).setId(request.getId()).build());
                        monitoringProcessExecutorService.submit(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    future.get();
                                    sentBlocks.add(hash);
                                    synchronized (updateLock) {
                                        updateLock.notifyAll();
                                    }
                                    //TODO retry on error, register error and throw on watcher
                                } catch (InterruptedException ex) {
                                    //return and do nothing
                                } catch (ExecutionException ex) {
                                    uploadError.set(ex);
                                    synchronized (updateLock) {
                                        updateLock.notifyAll();
                                    }
                                }
                            }
                        });
                    } catch (Exception ex) {
                        logger.error("error handling block request", ex);
                        connectionHandler.sendMessage(Response.newBuilder()
                                .setCode(BlockExchageProtos.ErrorCode.GENERIC).setId(request.getId()).build());
                        uploadError.set(ex);
                        synchronized (updateLock) {
                            updateLock.notifyAll();
                        }
                    }
                }
            }
        };
        connectionHandler.getEventBus().register(listener);
        logger.debug("send index update for file = {}", path);
        final Object indexListener = new Object() {

            @Subscribe
            public void handleIndexRecordAquiredEvent(IndexHandler.IndexRecordAquiredEvent event) {
                if (equal(event.getFolder(), folder)) {
                    for (FileInfo fileInfo : event.getNewRecords()) {
                        if (equal(fileInfo.getPath(), path)
                                && equal(fileInfo.getHash(), dataSource.getHash())) { //TODO check not invalid
                            //                                sentBlocks.addAll(dataSource.getHashes());
                            isCompleted.set(true);
                            synchronized (updateLock) {
                                updateLock.notifyAll();
                            }
                        }
                    }
                }
            }
        };
        if (indexHandler != null) {
            indexHandler.getEventBus().register(indexListener);
        }
        final IndexUpdate indexUpdate = sendIndexUpdate(folder,
                BlockExchageProtos.FileInfo.newBuilder().setName(path).setSize(fileSize)
                        .setType(BlockExchageProtos.FileInfoType.FILE).addAllBlocks(dataSource.getBlocks()),
                fileInfo == null ? null : fileInfo.getVersionList()).getRight();
        final FileUploadObserver messageUploadObserver = new FileUploadObserver() {
            @Override
            public void close() {
                logger.debug("closing upload process");
                try {
                    connectionHandler.getEventBus().unregister(listener);
                    monitoringProcessExecutorService.shutdown();
                    if (indexHandler != null) {
                        indexHandler.getEventBus().unregister(indexListener);
                    }
                } catch (Exception ex) {
                }
                if (closeConnection && connectionHandler != null) {
                    connectionHandler.close();
                }
                if (indexHandler != null) {
                    FileInfo fileInfo = indexHandler.pushRecord(indexUpdate.getFolder(),
                            Iterables.getOnlyElement(indexUpdate.getFilesList()));
                    logger.info("sent file info record = {}", fileInfo);
                }
            }

            @Override
            public double getProgress() {
                return isCompleted() ? 1d : sentBlocks.size() / ((double) dataSource.getHashes().size());
            }

            @Override
            public String getProgressMessage() {
                return (Math.round(getProgress() * 1000d) / 10d) + "% " + sentBlocks.size() + "/"
                        + dataSource.getHashes().size();
            }

            @Override
            public boolean isCompleted() {
                //                    return sentBlocks.size() == dataSource.getHashes().size();
                return isCompleted.get();
            }

            @Override
            public double waitForProgressUpdate() throws InterruptedException {
                synchronized (updateLock) {
                    updateLock.wait();
                }
                if (uploadError.get() != null) {
                    throw new RuntimeException(uploadError.get());
                }
                return getProgress();
            }

            @Override
            public DataSource getDataSource() {
                return dataSource;
            }

        };
        return messageUploadObserver;
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

From source file:fr.jmmc.smprsc.data.stub.StubMetaData.java

/**
 * Upload application complete description to JMMC central repository (only if not known yet).
 *
 * @param preferenceInstance the jMCS Preference object in which silent report flag is stored
 * @param preferenceName the jMCS Preference key that point to the silent report flag value
 *///  w  w  w.ja v  a 2  s  .  c o  m
public void reportToCentralRepository(final Preferences preferenceInstance, final String preferenceName) {

    // Make all the network stuff run in the background
    ThreadExecutors.getGenericExecutor().submit(new Runnable() {
        AtomicBoolean shouldPhoneHome = new AtomicBoolean(true);
        ApplicationReportingForm dialog = null;

        @Override
        public void run() {

            // If the current application does not exist in the central repository
            if (isNotKnownYet()) {

                // If user wants to explicitly choose to report or not
                final boolean silently = preferenceInstance.getPreferenceAsBoolean(preferenceName);
                if (!silently) {
                    // Ask user if it is OK to phone application description back home
                    SwingUtils.invokeAndWaitEDT(new Runnable() {
                        /**
                         * Synchronized by EDT
                         */
                        @Override
                        public void run() {
                            _logger.debug("Showing report window for '{}' application", _applicationName);
                            dialog = new ApplicationReportingForm(_applicationName);
                            shouldPhoneHome.set(dialog.shouldSubmit());
                            final boolean shouldSilentlySubmit = dialog.shouldSilentlySubmit();
                            if (shouldSilentlySubmit != silently) {
                                try {
                                    preferenceInstance.setPreference(preferenceName, shouldSilentlySubmit);
                                    preferenceInstance.saveToFile();
                                } catch (PreferencesException ex) {
                                    _logger.warn("Could not save silent report state to preference : ", ex);
                                }
                            }
                        }
                    });
                } else {
                    _logger.info("Silently reporting '{}' unknown application", _applicationName);
                }

                // If the user agreed to report unknown app
                if (shouldPhoneHome.get()) {
                    if (dialog == null) { // Silently
                        serializeMetaData(null, null); // Report without further data
                    } else { // Explicitly
                        final String userEmail = dialog.getUserEmail();
                        final String applicationURL = dialog.getApplicationURL();
                        serializeMetaData(userEmail, applicationURL);
                    }

                    final String xmlRepresentation = marshallApplicationDescription();
                    postXMLToRegistry(xmlRepresentation);
                }
            }
        }
    });
}

From source file:com.arpnetworking.metrics.impl.ApacheHttpSinkTest.java

@Test
public void testPostSuccess() throws InterruptedException {
    final String start = Instant.now().minusMillis(812).atZone(ZoneId.of("UTC"))
            .format(DateTimeFormatter.ISO_INSTANT);
    final String end = Instant.now().atZone(ZoneId.of("UTC")).format(DateTimeFormatter.ISO_INSTANT);
    final String id = UUID.randomUUID().toString();

    _wireMockRule.stubFor(WireMock.requestMatching(new RequestValueMatcher(r -> {
        // Annotations
        Assert.assertEquals(7, r.getAnnotationsCount());
        assertAnnotation(r.getAnnotationsList(), "foo", "bar");
        assertAnnotation(r.getAnnotationsList(), "_service", "myservice");
        assertAnnotation(r.getAnnotationsList(), "_cluster", "mycluster");
        assertAnnotation(r.getAnnotationsList(), "_start", start);
        assertAnnotation(r.getAnnotationsList(), "_end", end);
        assertAnnotation(r.getAnnotationsList(), "_id", id);

        // Dimensions
        Assert.assertEquals(3, r.getDimensionsCount());
        assertDimension(r.getDimensionsList(), "host", "some.host.com");
        assertDimension(r.getDimensionsList(), "service", "myservice");
        assertDimension(r.getDimensionsList(), "cluster", "mycluster");

        // Samples
        assertSample(r.getTimersList(), "timerLong", 123L, ClientV2.Unit.Type.Value.SECOND,
                ClientV2.Unit.Scale.Value.NANO);
        assertSample(r.getTimersList(), "timerInt", 123, ClientV2.Unit.Type.Value.SECOND,
                ClientV2.Unit.Scale.Value.NANO);
        assertSample(r.getTimersList(), "timerShort", (short) 123, ClientV2.Unit.Type.Value.SECOND,
                ClientV2.Unit.Scale.Value.NANO);
        assertSample(r.getTimersList(), "timerByte", (byte) 123, ClientV2.Unit.Type.Value.SECOND,
                ClientV2.Unit.Scale.Value.NANO);
        assertSample(r.getCountersList(), "counter", 8d);
        assertSample(r.getGaugesList(), "gauge", 10d, ClientV2.Unit.Type.Value.BYTE,
                ClientV2.Unit.Scale.Value.UNIT);
    })).willReturn(WireMock.aResponse().withStatus(200)));

    final AtomicBoolean assertionResult = new AtomicBoolean(false);
    final Semaphore semaphore = new Semaphore(0);
    final Sink sink = new ApacheHttpSink.Builder()
            .setUri(URI.create("http://localhost:" + _wireMockRule.port() + PATH))
            .setEventHandler(new AttemptCompletedAssertionHandler(assertionResult, 1, 451, true,
                    new CompletionHandler(semaphore)))
            .build();//  www.j a v  a  2s  .  c  o m

    final Map<String, String> annotations = new LinkedHashMap<>();
    annotations.put("foo", "bar");
    annotations.put("_start", start);
    annotations.put("_end", end);
    annotations.put("_host", "some.host.com");
    annotations.put("_service", "myservice");
    annotations.put("_cluster", "mycluster");
    annotations.put("_id", id);

    final TsdEvent event = new TsdEvent(annotations,
            createQuantityMap("timerLong", TsdQuantity.newInstance(123L, Units.NANOSECOND), "timerInt",
                    TsdQuantity.newInstance(123, Units.NANOSECOND), "timerShort",
                    TsdQuantity.newInstance((short) 123, Units.NANOSECOND), "timerByte",
                    TsdQuantity.newInstance((byte) 123, Units.NANOSECOND)),
            createQuantityMap("counter", TsdQuantity.newInstance(8d, null)),
            createQuantityMap("gauge", TsdQuantity.newInstance(10d, Units.BYTE)));

    sink.record(event);
    semaphore.acquire();

    // Ensure expected handler was invoked
    Assert.assertTrue(assertionResult.get());

    // Request matcher
    final RequestPatternBuilder requestPattern = WireMock.postRequestedFor(WireMock.urlEqualTo(PATH))
            .withHeader("Content-Type", WireMock.equalTo("application/octet-stream"));

    // Assert that data was sent
    _wireMockRule.verify(1, requestPattern);
    Assert.assertTrue(_wireMockRule.findUnmatchedRequests().getRequests().isEmpty());
}

From source file:de.jackwhite20.japs.client.cache.impl.PubSubCacheImpl.java

@Override
public Future<Boolean> has(String key) {

    if (key == null || key.isEmpty()) {
        throw new IllegalArgumentException("key cannot be null or empty");
    }/*from   ww w  .j  a v a  2s  .com*/

    return executorService.submit(() -> {

        int id = CALLBACK_COUNTER.getAndIncrement();

        AtomicBoolean has = new AtomicBoolean(false);

        CountDownLatch countDownLatch = new CountDownLatch(1);

        callbacks.put(id, new Consumer<JSONObject>() {

            @Override
            public void accept(JSONObject jsonObject) {

                has.set(jsonObject.getBoolean("has"));

                countDownLatch.countDown();
            }
        });

        JSONObject jsonObject = new JSONObject().put("op", OpCode.OP_CACHE_HAS.getCode()).put("key", key)
                .put("id", id);

        write(jsonObject);

        countDownLatch.await();

        return has.get();
    });
}

From source file:com.streamsets.pipeline.stage.bigquery.destination.BigQueryTarget.java

@Override
public void write(Batch batch) throws StageException {
    Map<TableId, List<Record>> tableIdToRecords = new LinkedHashMap<>();
    Map<Long, Record> requestIndexToRecords = new LinkedHashMap<>();

    if (batch.getRecords().hasNext()) {
        ELVars elVars = getContext().createELVars();
        batch.getRecords().forEachRemaining(record -> {
            RecordEL.setRecordInContext(elVars, record);
            try {
                String datasetName = dataSetEval.eval(elVars, conf.datasetEL, String.class);
                String tableName = tableNameELEval.eval(elVars, conf.tableNameEL, String.class);
                TableId tableId = TableId.of(datasetName, tableName);
                if (tableIdExistsCache.get(tableId)) {
                    List<Record> tableIdRecords = tableIdToRecords.computeIfAbsent(tableId,
                            t -> new ArrayList<>());
                    tableIdRecords.add(record);
                } else {
                    getContext().toError(record, Errors.BIGQUERY_17, datasetName, tableName,
                            conf.credentials.projectId);
                }/*from  ww w.  java2s  .co  m*/
            } catch (ELEvalException e) {
                LOG.error("Error evaluating DataSet/TableName EL", e);
                getContext().toError(record, Errors.BIGQUERY_10, e);
            } catch (ExecutionException e) {
                LOG.error("Error when checking exists for tableId, Reason : {}", e);
                Throwable rootCause = Throwables.getRootCause(e);
                getContext().toError(record, Errors.BIGQUERY_13, rootCause);
            }
        });

        tableIdToRecords.forEach((tableId, records) -> {
            final AtomicLong index = new AtomicLong(0);
            final AtomicBoolean areThereRecordsToWrite = new AtomicBoolean(false);
            InsertAllRequest.Builder insertAllRequestBuilder = InsertAllRequest.newBuilder(tableId);
            records.forEach(record -> {
                try {
                    String insertId = getInsertIdForRecord(elVars, record);
                    Map<String, ?> rowContent = convertToRowObjectFromRecord(record);
                    if (rowContent.isEmpty()) {
                        throw new OnRecordErrorException(record, Errors.BIGQUERY_14);
                    }
                    insertAllRequestBuilder.addRow(insertId, rowContent);
                    areThereRecordsToWrite.set(true);
                    requestIndexToRecords.put(index.getAndIncrement(), record);
                } catch (OnRecordErrorException e) {
                    LOG.error("Error when converting record {} to row, Reason : {} ",
                            record.getHeader().getSourceId(), e.getMessage());
                    getContext().toError(record, e.getErrorCode(), e.getParams());
                }
            });

            if (areThereRecordsToWrite.get()) {
                insertAllRequestBuilder.setIgnoreUnknownValues(conf.ignoreInvalidColumn);
                insertAllRequestBuilder.setSkipInvalidRows(false);

                InsertAllRequest request = insertAllRequestBuilder.build();

                if (!request.getRows().isEmpty()) {
                    try {
                        InsertAllResponse response = bigQuery.insertAll(request);
                        if (response.hasErrors()) {
                            response.getInsertErrors().forEach((requestIdx, errors) -> {
                                Record record = requestIndexToRecords.get(requestIdx);
                                String messages = COMMA_JOINER.join(errors.stream()
                                        .map(BigQueryError::getMessage).collect(Collectors.toList()));
                                String reasons = COMMA_JOINER.join(errors.stream().map(BigQueryError::getReason)
                                        .collect(Collectors.toList()));
                                LOG.error("Error when inserting record {}, Reasons : {}, Messages : {}",
                                        record.getHeader().getSourceId(), reasons, messages);
                                getContext().toError(record, Errors.BIGQUERY_11, reasons, messages);
                            });
                        }
                    } catch (BigQueryException e) {
                        LOG.error(Errors.BIGQUERY_13.getMessage(), e);
                        //Put all records to error.
                        for (long i = 0; i < request.getRows().size(); i++) {
                            Record record = requestIndexToRecords.get(i);
                            getContext().toError(record, Errors.BIGQUERY_13, e);
                        }
                    }
                }
            }
        });
    }
}

From source file:io.pravega.client.stream.impl.ReaderGroupStateManager.java

/**
 * Handles a segment being completed by calling the controller to gather all successors to the completed segment.
 *///from   w  w w.j a  va  2  s  . c  o  m
void handleEndOfSegment(Segment segmentCompleted) throws ReinitializationRequiredException {
    val successors = getAndHandleExceptions(controller.getSuccessors(segmentCompleted), RuntimeException::new);
    AtomicBoolean reinitRequired = new AtomicBoolean(false);
    sync.updateState(state -> {
        if (!state.isReaderOnline(readerId)) {
            reinitRequired.set(true);
            return null;
        }
        return Collections.singletonList(
                new SegmentCompleted(readerId, segmentCompleted, successors.getSegmentToPredecessor()));
    });
    if (reinitRequired.get()) {
        throw new ReinitializationRequiredException();
    }
    acquireTimer.zero();
}

From source file:ai.susi.mind.SusiSkill.java

/**
 * if no keys are given, we compute them from the given phrases
 * @param phrases// ww w  .  j av a  2s  . c om
 * @return
 */
private static JSONArray computeKeysFromPhrases(List<SusiPhrase> phrases) {
    Set<String> t = new LinkedHashSet<>();

    // create a list of token sets from the phrases
    List<Set<String>> ptl = new ArrayList<>();
    final AtomicBoolean needsCatchall = new AtomicBoolean(false);
    phrases.forEach(phrase -> {
        Set<String> s = new HashSet<>();
        for (String token : SPACE_PATTERN.split(phrase.getPattern().toString())) {
            String m = SusiPhrase.extractMeat(token.toLowerCase());
            if (m.length() > 1)
                s.add(m);
        }
        // if there is no meat inside, it will not be possible to access the skill without the catchall skill, so remember that
        if (s.size() == 0)
            needsCatchall.set(true);

        ptl.add(s);
    });

    // this is a kind of emergency case where we need a catchall skill because otherwise we cannot access one of the phrases
    JSONArray a = new JSONArray();
    if (needsCatchall.get())
        return a.put(CATCHALL_KEY);

    // collect all token
    ptl.forEach(set -> set.forEach(token -> t.add(token)));

    // if no tokens are available, return the catchall key
    if (t.size() == 0)
        return a.put(CATCHALL_KEY);

    // make a copy to make it possible to use the original key set again
    Set<String> tc = new LinkedHashSet<>();
    t.forEach(c -> tc.add(c));

    // remove all token that do not appear in all phrases
    ptl.forEach(set -> {
        Iterator<String> i = t.iterator();
        while (i.hasNext())
            if (!set.contains(i.next()))
                i.remove();
    });

    // if no token is left, use the original tc set and add all keys
    if (t.size() == 0) {
        tc.forEach(c -> a.put(c));
        return a;
    }

    // use only the first token, because that appears in all the phrases
    return new JSONArray().put(t.iterator().next());
}

From source file:com.bt.aloha.media.testing.mockphones.ConvediaMockphoneBean.java

private void processMsmlCancelMediaRequest(final String dialogId, final String commandId) {
    final AtomicBoolean needToSendDtmfTerminatedResponse = new AtomicBoolean(false);
    final DialogInfo dialogInfo = getDialogCollection().get(dialogId);
    String originalAudioFileUri = dialogInfo.getApplicationData();
    String responseContent = null;
    if (originalAudioFileUri.indexOf(PLAY_TERMINATED_STRING_PROPERTY_KEY) > -1) {
        responseContent = new MsmlAnnouncementResponse(commandId, ONE_HUNDRED_MS, PLAY_TERMINATED).getXml();
    } else if (originalAudioFileUri.indexOf(DTMF_PLAY_TERMINATED_STRING_PROPERTY_KEY) > -1) {
        responseContent = new MsmlPromptAndCollectDigitsAnnouncementResponse(commandId, ONE_HUNDRED_MS,
                PLAY_TERMINATED).getXml();
    } else if (originalAudioFileUri.indexOf(DTMF_TERMINATED_STRING_PROPERTY_KEY) > -1) {
        responseContent = new MsmlPromptAndCollectDigitsAnnouncementResponse(commandId, ONE_HUNDRED_MS,
                "play.complete").getXml();
        needToSendDtmfTerminatedResponse.set(true);
    }/*  www .  j a v  a 2 s  .c  o m*/
    sendMediaResponse(dialogId, commandId, responseContent);

    if (needToSendDtmfTerminatedResponse.get()) {
        responseContent = new MsmlPromptAndCollectDigitsCollectedResponse(commandId, ONE_HUNDRED_MS,
                "dtmf.terminated").getXml();
        sendMediaResponse(dialogId, commandId, responseContent);
    }
}

From source file:io.pravega.controller.eventProcessor.impl.SerializedRequestHandlerTest.java

@Test(timeout = 10000)
public void testPostponeEvent() throws InterruptedException, ExecutionException {
    AtomicInteger postponeS1e1Count = new AtomicInteger();
    AtomicInteger postponeS1e2Count = new AtomicInteger();
    AtomicBoolean allowCompletion = new AtomicBoolean(false);

    SerializedRequestHandler<TestEvent> requestHandler = new SerializedRequestHandler<TestEvent>(
            executorService()) {//w  w w  .  ja  v a 2s  .  co m
        @Override
        public CompletableFuture<Void> processEvent(TestEvent event) {
            if (!event.future.isDone()) {
                return Futures.failedFuture(new TestPostponeException());
            }
            return event.getFuture();
        }

        @Override
        public boolean toPostpone(TestEvent event, long pickupTime, Throwable exception) {

            boolean retval = true;

            if (allowCompletion.get()) {
                if (event.number == 1) {
                    postponeS1e1Count.incrementAndGet();
                    retval = exception instanceof TestPostponeException && postponeS1e1Count.get() < 2;
                }

                if (event.number == 2) {
                    postponeS1e2Count.incrementAndGet();
                    retval = exception instanceof TestPostponeException
                            && (System.currentTimeMillis() - pickupTime < Duration.ofMillis(100).toMillis());
                }
            }

            return retval;
        }
    };

    List<Pair<TestEvent, CompletableFuture<Void>>> stream1Queue = requestHandler
            .getEventQueueForKey(getKeyForStream("scope", "stream1"));
    assertNull(stream1Queue);
    // post 3 work for stream1
    TestEvent s1e1 = new TestEvent("scope", "stream1", 1);
    CompletableFuture<Void> s1p1 = requestHandler.process(s1e1);
    TestEvent s1e2 = new TestEvent("scope", "stream1", 2);
    CompletableFuture<Void> s1p2 = requestHandler.process(s1e2);
    TestEvent s1e3 = new TestEvent("scope", "stream1", 3);
    CompletableFuture<Void> s1p3 = requestHandler.process(s1e3);

    // post events for some more arbitrary streams in background
    AtomicBoolean stop = new AtomicBoolean(false);

    runBackgroundStreamProcessing("stream2", requestHandler, stop);
    runBackgroundStreamProcessing("stream3", requestHandler, stop);
    runBackgroundStreamProcessing("stream4", requestHandler, stop);

    s1e3.complete();
    // verify that s1p3 completes.
    assertTrue(Futures.await(s1p3));
    // verify that s1e1 and s1e2 are still not complete.
    assertTrue(!s1e1.getFuture().isDone());
    assertTrue(!s1p1.isDone());
    assertTrue(!s1e2.getFuture().isDone());
    assertTrue(!s1p2.isDone());

    // Allow completion
    allowCompletion.set(true);

    assertFalse(Futures.await(s1p1));
    assertFalse(Futures.await(s1p2));
    AssertExtensions.assertThrows("", s1p1::join, e -> Exceptions.unwrap(e) instanceof TestPostponeException);
    AssertExtensions.assertThrows("", s1p2::join, e -> Exceptions.unwrap(e) instanceof TestPostponeException);
    assertTrue(postponeS1e1Count.get() == 2);
    assertTrue(postponeS1e2Count.get() > 0);
    stop.set(true);
}