Search in sources :

Example 1 with ForwardingListeningExecutorService

use of com.google.common.util.concurrent.ForwardingListeningExecutorService in project druid by druid-io.

the class CachingClusteredClientTest method testOutOfOrderBackgroundCachePopulation.

@Test
public void testOutOfOrderBackgroundCachePopulation() {
    // to trigger the actual execution when we are ready to shuffle the order.
    abstract class DrainTask implements Runnable {
    }
    final ForwardingListeningExecutorService randomizingExecutorService = new ForwardingListeningExecutorService() {

        final ConcurrentLinkedDeque<Pair<SettableFuture, Object>> taskQueue = new ConcurrentLinkedDeque<>();

        final ListeningExecutorService delegate = MoreExecutors.listeningDecorator(// are complete before moving on to the next query run.
        Execs.directExecutor());

        @Override
        protected ListeningExecutorService delegate() {
            return delegate;
        }

        private <T> ListenableFuture<T> maybeSubmitTask(Object task, boolean wait) {
            if (wait) {
                SettableFuture<T> future = SettableFuture.create();
                taskQueue.addFirst(Pair.of(future, task));
                return future;
            } else {
                List<Pair<SettableFuture, Object>> tasks = Lists.newArrayList(taskQueue.iterator());
                Collections.shuffle(tasks, new Random(0));
                for (final Pair<SettableFuture, Object> pair : tasks) {
                    ListenableFuture future = pair.rhs instanceof Callable ? delegate.submit((Callable) pair.rhs) : delegate.submit((Runnable) pair.rhs);
                    Futures.addCallback(future, new FutureCallback() {

                        @Override
                        public void onSuccess(@Nullable Object result) {
                            pair.lhs.set(result);
                        }

                        @Override
                        public void onFailure(Throwable t) {
                            pair.lhs.setException(t);
                        }
                    });
                }
            }
            return task instanceof Callable ? delegate.submit((Callable) task) : (ListenableFuture<T>) delegate.submit((Runnable) task);
        }

        @SuppressWarnings("ParameterPackage")
        @Override
        public <T> ListenableFuture<T> submit(Callable<T> task) {
            return maybeSubmitTask(task, true);
        }

        @Override
        public ListenableFuture<?> submit(Runnable task) {
            if (task instanceof DrainTask) {
                return maybeSubmitTask(task, false);
            } else {
                return maybeSubmitTask(task, true);
            }
        }
    };
    client = makeClient(new BackgroundCachePopulator(randomizingExecutorService, JSON_MAPPER, new CachePopulatorStats(), -1));
    // callback to be run every time a query run is complete, to ensure all background
    // caching tasks are executed, and cache is populated before we move onto the next query
    queryCompletedCallback = new Runnable() {

        @Override
        public void run() {
            try {
                randomizingExecutorService.submit(new DrainTask() {

                    @Override
                    public void run() {
                    // no-op
                    }
                }).get();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    };
    final Druids.TimeseriesQueryBuilder builder = Druids.newTimeseriesQueryBuilder().dataSource(DATA_SOURCE).intervals(SEG_SPEC).filters(DIM_FILTER).granularity(GRANULARITY).aggregators(AGGS).postAggregators(POST_AGGS).context(CONTEXT).randomQueryId();
    QueryRunner runner = new FinalizeResultsQueryRunner(getDefaultQueryRunner(), new TimeseriesQueryQueryToolChest());
    testQueryCaching(runner, builder.build(), Intervals.of("2011-01-05/2011-01-10"), makeTimeResults(DateTimes.of("2011-01-05"), 85, 102, DateTimes.of("2011-01-06"), 412, 521, DateTimes.of("2011-01-07"), 122, 21894, DateTimes.of("2011-01-08"), 5, 20, DateTimes.of("2011-01-09"), 18, 521), Intervals.of("2011-01-10/2011-01-13"), makeTimeResults(DateTimes.of("2011-01-10"), 85, 102, DateTimes.of("2011-01-11"), 412, 521, DateTimes.of("2011-01-12"), 122, 21894));
}
Also used : SettableFuture(com.google.common.util.concurrent.SettableFuture) ForwardingListeningExecutorService(com.google.common.util.concurrent.ForwardingListeningExecutorService) TimeseriesQueryQueryToolChest(org.apache.druid.query.timeseries.TimeseriesQueryQueryToolChest) Callable(java.util.concurrent.Callable) Random(java.util.Random) CachePopulatorStats(org.apache.druid.client.cache.CachePopulatorStats) Druids(org.apache.druid.query.Druids) FutureCallback(com.google.common.util.concurrent.FutureCallback) Pair(org.apache.druid.java.util.common.Pair) BackgroundCachePopulator(org.apache.druid.client.cache.BackgroundCachePopulator) IOException(java.io.IOException) FinalizeResultsQueryRunner(org.apache.druid.query.FinalizeResultsQueryRunner) QueryRunner(org.apache.druid.query.QueryRunner) ConcurrentLinkedDeque(java.util.concurrent.ConcurrentLinkedDeque) FinalizeResultsQueryRunner(org.apache.druid.query.FinalizeResultsQueryRunner) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) ListeningExecutorService(com.google.common.util.concurrent.ListeningExecutorService) ForwardingListeningExecutorService(com.google.common.util.concurrent.ForwardingListeningExecutorService) Test(org.junit.Test)

Example 2 with ForwardingListeningExecutorService

use of com.google.common.util.concurrent.ForwardingListeningExecutorService in project druid by druid-io.

the class CachingClusteredClientTest method testOutOfOrderBackgroundCachePopulation.

@Test
public void testOutOfOrderBackgroundCachePopulation() throws Exception {
    // to trigger the actual execution when we are ready to shuffle the order.
    abstract class DrainTask implements Runnable {
    }
    final ForwardingListeningExecutorService randomizingExecutorService = new ForwardingListeningExecutorService() {

        final ConcurrentLinkedDeque<Pair<SettableFuture, Object>> taskQueue = new ConcurrentLinkedDeque<>();

        final ListeningExecutorService delegate = MoreExecutors.listeningDecorator(// are complete before moving on to the next query run.
        MoreExecutors.sameThreadExecutor());

        @Override
        protected ListeningExecutorService delegate() {
            return delegate;
        }

        private <T> ListenableFuture<T> maybeSubmitTask(Object task, boolean wait) {
            if (wait) {
                SettableFuture<T> future = SettableFuture.create();
                taskQueue.addFirst(Pair.<SettableFuture, Object>of(future, task));
                return future;
            } else {
                List<Pair<SettableFuture, Object>> tasks = Lists.newArrayList(taskQueue.iterator());
                Collections.shuffle(tasks, new Random(0));
                for (final Pair<SettableFuture, Object> pair : tasks) {
                    ListenableFuture future = pair.rhs instanceof Callable ? delegate.submit((Callable) pair.rhs) : delegate.submit((Runnable) pair.rhs);
                    Futures.addCallback(future, new FutureCallback() {

                        @Override
                        public void onSuccess(@Nullable Object result) {
                            pair.lhs.set(result);
                        }

                        @Override
                        public void onFailure(Throwable t) {
                            pair.lhs.setException(t);
                        }
                    });
                }
            }
            return task instanceof Callable ? delegate.submit((Callable) task) : (ListenableFuture<T>) delegate.submit((Runnable) task);
        }

        @Override
        public <T> ListenableFuture<T> submit(Callable<T> task) {
            return maybeSubmitTask(task, true);
        }

        @Override
        public ListenableFuture<?> submit(Runnable task) {
            if (task instanceof DrainTask) {
                return maybeSubmitTask(task, false);
            } else {
                return maybeSubmitTask(task, true);
            }
        }
    };
    client = makeClient(randomizingExecutorService);
    // callback to be run every time a query run is complete, to ensure all background
    // caching tasks are executed, and cache is populated before we move onto the next query
    queryCompletedCallback = new Runnable() {

        @Override
        public void run() {
            try {
                randomizingExecutorService.submit(new DrainTask() {

                    @Override
                    public void run() {
                    // no-op
                    }
                }).get();
            } catch (Exception e) {
                Throwables.propagate(e);
            }
        }
    };
    final Druids.TimeseriesQueryBuilder builder = Druids.newTimeseriesQueryBuilder().dataSource(DATA_SOURCE).intervals(SEG_SPEC).filters(DIM_FILTER).granularity(GRANULARITY).aggregators(AGGS).postAggregators(POST_AGGS).context(CONTEXT);
    QueryRunner runner = new FinalizeResultsQueryRunner(client, new TimeseriesQueryQueryToolChest(QueryRunnerTestHelper.NoopIntervalChunkingQueryRunnerDecorator()));
    testQueryCaching(runner, builder.build(), new Interval("2011-01-05/2011-01-10"), makeTimeResults(new DateTime("2011-01-05"), 85, 102, new DateTime("2011-01-06"), 412, 521, new DateTime("2011-01-07"), 122, 21894, new DateTime("2011-01-08"), 5, 20, new DateTime("2011-01-09"), 18, 521), new Interval("2011-01-10/2011-01-13"), makeTimeResults(new DateTime("2011-01-10"), 85, 102, new DateTime("2011-01-11"), 412, 521, new DateTime("2011-01-12"), 122, 21894));
}
Also used : SettableFuture(com.google.common.util.concurrent.SettableFuture) ForwardingListeningExecutorService(com.google.common.util.concurrent.ForwardingListeningExecutorService) TimeseriesQueryQueryToolChest(io.druid.query.timeseries.TimeseriesQueryQueryToolChest) Callable(java.util.concurrent.Callable) DateTime(org.joda.time.DateTime) Random(java.util.Random) Druids(io.druid.query.Druids) FutureCallback(com.google.common.util.concurrent.FutureCallback) Pair(io.druid.java.util.common.Pair) IOException(java.io.IOException) FinalizeResultsQueryRunner(io.druid.query.FinalizeResultsQueryRunner) QueryRunner(io.druid.query.QueryRunner) ConcurrentLinkedDeque(java.util.concurrent.ConcurrentLinkedDeque) FinalizeResultsQueryRunner(io.druid.query.FinalizeResultsQueryRunner) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) ListeningExecutorService(com.google.common.util.concurrent.ListeningExecutorService) ForwardingListeningExecutorService(com.google.common.util.concurrent.ForwardingListeningExecutorService) Interval(org.joda.time.Interval) Test(org.junit.Test) GroupByQueryRunnerTest(io.druid.query.groupby.GroupByQueryRunnerTest)

Example 3 with ForwardingListeningExecutorService

use of com.google.common.util.concurrent.ForwardingListeningExecutorService in project jackrabbit-oak by apache.

the class IndexCopierTest method copyInProgressStats.

@Test
public void copyInProgressStats() throws Exception {
    Directory baseDir = new RAMDirectory();
    IndexDefinition defn = new IndexDefinition(root, builder.getNodeState(), "/foo");
    final List<ListenableFuture<?>> submittedTasks = Lists.newArrayList();
    ExecutorService executor = new ForwardingListeningExecutorService() {

        @Override
        protected ListeningExecutorService delegate() {
            return MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
        }

        @Override
        public void execute(Runnable command) {
            submittedTasks.add(super.submit(command));
        }
    };
    IndexCopier c1 = new RAMIndexCopier(baseDir, executor, getWorkDir());
    final CountDownLatch copyProceed = new CountDownLatch(1);
    final CountDownLatch copyRequestArrived = new CountDownLatch(1);
    TestRAMDirectory remote = new TestRAMDirectory() {

        @Override
        public void copy(Directory to, String src, String dest, IOContext context) throws IOException {
            copyRequestArrived.countDown();
            try {
                copyProceed.await();
            } catch (InterruptedException e) {
            }
            super.copy(to, src, dest, context);
        }
    };
    Directory wrapped = c1.wrapForRead("/foo", defn, remote, INDEX_DATA_CHILD_NAME);
    byte[] t1 = writeFile(remote, "t1");
    // 1. Trigger a read which should go to remote
    readAndAssert(wrapped, "t1", t1);
    copyRequestArrived.await();
    assertEquals(1, c1.getCopyInProgressCount());
    assertEquals(1, remote.openedFiles.size());
    // 2. Trigger another read and this should also be
    // served from remote
    readAndAssert(wrapped, "t1", t1);
    assertEquals(1, c1.getCopyInProgressCount());
    assertEquals(IOUtils.humanReadableByteCount(t1.length), c1.getCopyInProgressSize());
    assertEquals(1, c1.getCopyInProgressDetails().length);
    System.out.println(Arrays.toString(c1.getCopyInProgressDetails()));
    assertEquals(2, remote.openedFiles.size());
    // 3. Perform copy
    copyProceed.countDown();
    Futures.allAsList(submittedTasks).get();
    remote.reset();
    // 4. Now read again after copy is done
    readAndAssert(wrapped, "t1", t1);
    // Now read should be served from local and not from remote
    assertEquals(0, remote.openedFiles.size());
    assertEquals(0, c1.getCopyInProgressCount());
    executor.shutdown();
}
Also used : ForwardingListeningExecutorService(com.google.common.util.concurrent.ForwardingListeningExecutorService) CountDownLatch(java.util.concurrent.CountDownLatch) RAMDirectory(org.apache.lucene.store.RAMDirectory) ForwardingListeningExecutorService(com.google.common.util.concurrent.ForwardingListeningExecutorService) ListeningExecutorService(com.google.common.util.concurrent.ListeningExecutorService) ExecutorService(java.util.concurrent.ExecutorService) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) IOContext(org.apache.lucene.store.IOContext) Directory(org.apache.lucene.store.Directory) RAMDirectory(org.apache.lucene.store.RAMDirectory) FilterDirectory(org.apache.lucene.store.FilterDirectory) Test(org.junit.Test)

Aggregations

ForwardingListeningExecutorService (com.google.common.util.concurrent.ForwardingListeningExecutorService)3 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)3 ListeningExecutorService (com.google.common.util.concurrent.ListeningExecutorService)3 Test (org.junit.Test)3 FutureCallback (com.google.common.util.concurrent.FutureCallback)2 SettableFuture (com.google.common.util.concurrent.SettableFuture)2 IOException (java.io.IOException)2 Random (java.util.Random)2 Callable (java.util.concurrent.Callable)2 ConcurrentLinkedDeque (java.util.concurrent.ConcurrentLinkedDeque)2 Pair (io.druid.java.util.common.Pair)1 Druids (io.druid.query.Druids)1 FinalizeResultsQueryRunner (io.druid.query.FinalizeResultsQueryRunner)1 QueryRunner (io.druid.query.QueryRunner)1 GroupByQueryRunnerTest (io.druid.query.groupby.GroupByQueryRunnerTest)1 TimeseriesQueryQueryToolChest (io.druid.query.timeseries.TimeseriesQueryQueryToolChest)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 ExecutorService (java.util.concurrent.ExecutorService)1 BackgroundCachePopulator (org.apache.druid.client.cache.BackgroundCachePopulator)1 CachePopulatorStats (org.apache.druid.client.cache.CachePopulatorStats)1