Example usage for java.util.concurrent ScheduledExecutorService isShutdown

List of usage examples for java.util.concurrent ScheduledExecutorService isShutdown

Introduction

In this page you can find the example usage for java.util.concurrent ScheduledExecutorService isShutdown.

Prototype

boolean isShutdown();

Source Link

Document

Returns true if this executor has been shut down.

Usage

From source file:com.ntsync.android.sync.activities.PaymentVerificationService.java

/**
 * Starts PaymentData Verification Timer, if not already running and
 * PaymentData is open to verify/*from   ww w .j a v  a2 s .  com*/
 * */
public static void startVerificationTimer(final Context context) {
    if (SyncUtils.hasPaymentData(context)) {
        ScheduledExecutorService scheduler = SCHEDULER_REF.get();
        if (scheduler == null || scheduler.isShutdown()) {
            scheduler = Executors.newScheduledThreadPool(1);
            SCHEDULER_REF.set(scheduler);
        } else {
            // Timer aktiv
            return;
        }
        final ScheduledExecutorService sched = scheduler;

        final Runnable verifTimer = new Runnable() {
            public void run() {
                runVerifier(context, sched);
            }
        };
        // Verificate PaymentData every 1h for

        scheduler.scheduleAtFixedRate(verifTimer, VERIFICATION_INITIAL_DELAY, VERIFICATION_INTERVAL,
                TimeUnit.SECONDS);
    }
}

From source file:com.ah.be.license.AeroLicenseTimer.java

/**
 * Stop your defined license timer.//from www  .jav  a  2 s. c  om
 *
 * @param arg_Timer -
 * @param arg_Future -
 * @return String : the error message
 */
public static String stopLicenseTimer(ScheduledExecutorService arg_Timer, ScheduledFuture<?> arg_Future) {
    try {
        if (!arg_Timer.isShutdown()) {

            if (null != arg_Future) {
                arg_Future.cancel(false);
            }

            // Disable new tasks from being submitted.
            arg_Timer.shutdown();
            try {
                // Wait a while for existing tasks to terminate.
                if (!arg_Timer.awaitTermination(5, TimeUnit.SECONDS)) {
                    // Cancel currently executing tasks.
                    arg_Timer.shutdownNow();

                    // Wait a while for tasks to respond to being canceled.
                    if (!arg_Timer.awaitTermination(5, TimeUnit.SECONDS)) {
                        return "The license timer does not terminate.";
                    }
                }
            } catch (InterruptedException ie) {
                // (Re-)Cancel if current thread also interrupted.
                //arg_Timer.shutdownNow();
            }
        }
    } catch (Exception e) {
        return "There is something wrong with timer stop.";
    }
    return null;
}

From source file:org.codice.ddf.catalog.sourcepoller.PollerRunner.java

/**
 * {@link #startPolling(long)} must be called to schedule the polling.
 *
 * @param poller which to poll periodically at the configured poll interval
 * @param pollIntervalMinutes the poll interval. The poll interval can be updated via {@link
 *     #setPollIntervalMinutes(long)}.//from   w  ww.j av a 2  s.com
 * @param scheduledExecutorService the {@link ScheduledExecutorService} used to schedule the poll
 *     task to execute at the configured poll interval
 * @throws IllegalArgumentException if {@code pollIntervalMinutes} is less than {@value
 *     #MINIMUM_POLL_INTERVAL_MINUTES} or if the {@code scheduledExecutorService} {@link
 *     ScheduledExecutorService#isShutdown()}
 * @throws NullPointerException if any of the parameters are {@code null}
 */
protected PollerRunner(final Poller<K, V> poller, final long pollIntervalMinutes,
        final ScheduledExecutorService scheduledExecutorService) {
    this.poller = notNull(poller);
    if (scheduledExecutorService.isShutdown()) {
        throw new IllegalArgumentException("scheduledExecutorService argument may not be shutdown");
    }
    this.scheduledExecutorService = scheduledExecutorService;
    this.pollIntervalMinutes = validPollIntervalMinutes(pollIntervalMinutes);
}

From source file:com.brienwheeler.lib.concurrent.ExecutorsTest.java

@Test
public void testNewSingleThreadScheduledExecutor() {
    NamedThreadFactory threadFactory = new NamedThreadFactory(THREAD_FACTORY_NAME);
    ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(threadFactory);

    ScheduledFuture<?> future1 = executor.schedule(new NullRunnable(), 10, TimeUnit.MILLISECONDS);
    ScheduledFuture<Integer> future2 = executor.schedule(new IntCallable(1), 10, TimeUnit.MILLISECONDS);
    ScheduledFuture<?> future3 = executor.scheduleAtFixedRate(new NullRunnable(), 10, 10,
            TimeUnit.MILLISECONDS);
    ScheduledFuture<?> future4 = executor.scheduleWithFixedDelay(new NullRunnable(), 10, 10,
            TimeUnit.MILLISECONDS);

    List<Runnable> notRun = executor.shutdownNow();
    Assert.assertTrue(executor.isShutdown());
    Assert.assertEquals(4, notRun.size());
    Assert.assertTrue(CollectionUtils.containsInstance(notRun, future1));
    Assert.assertTrue(CollectionUtils.containsInstance(notRun, future2));
    Assert.assertTrue(CollectionUtils.containsInstance(notRun, future3));
    Assert.assertTrue(CollectionUtils.containsInstance(notRun, future4));
}

From source file:org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutorTest.java

@Test
public void shouldNotShutdownExecutorServicesSuppliedToGremlinExecutor() throws Exception {
    final ScheduledExecutorService service = Executors.newScheduledThreadPool(4, testingThreadFactory);
    final GremlinExecutor gremlinExecutor = GremlinExecutor.build().executorService(service)
            .scheduledExecutorService(service).create();

    gremlinExecutor.close();//from   w  ww.j av  a 2  s  .c om
    assertFalse(service.isShutdown());
    service.shutdown();
    service.awaitTermination(30000, TimeUnit.MILLISECONDS);
}

From source file:org.openhab.io.transport.modbus.internal.ModbusManagerImpl.java

@Activate
protected void activate(Map<String, Object> configProperties) {
    synchronized (this) {
        logger.info("Modbus manager activated");
        if (connectionPool == null) {
            constructConnectionPool();//from   w  w  w. j  a  va  2  s  .c o m
        }
        ScheduledExecutorService scheduledThreadPoolExecutor = this.scheduledThreadPoolExecutor;
        if (scheduledThreadPoolExecutor == null) {
            this.scheduledThreadPoolExecutor = scheduledThreadPoolExecutor = ThreadPoolManager
                    .getScheduledPool(MODBUS_POLLER_THREAD_POOL_NAME);
        }
        if (scheduledThreadPoolExecutor.isShutdown()) {
            logger.error("Thread pool is shut down! Aborting activation of ModbusMangerImpl");
            throw new IllegalStateException(
                    "Thread pool(s) shut down! Aborting activation of ModbusMangerImpl");
        }
        monitorFuture = scheduledThreadPoolExecutor.scheduleWithFixedDelay(this::logTaskQueueInfo, 0,
                MONITOR_QUEUE_INTERVAL_MILLIS, TimeUnit.MILLISECONDS);
    }
}

From source file:ome.formats.importer.gui.ImportHandler.java

/**
 * @param ex -scheduled executor service for background processing
 * @param viewer - parent//from ww w.j av  a 2  s .  co m
 * @param qTable - fileQueueTable to receive notifications
 * @param config - passed in config
 * @param library - passed in library
 * @param containers - importContainers
 */
public ImportHandler(final ScheduledExecutorService ex, GuiImporter viewer, FileQueueTable qTable,
        ImportConfig config, ImportLibrary library, ImportContainer[] containers) {

    this.config = config;
    this.library = library;
    this.importContainer = containers;
    if (viewer.getHistoryTable() != null) {
        this.db = viewer.getHistoryTable().db;
    } else {
        this.db = null;
    }

    if (runState == true) {
        log.error("ImportHandler running twice");
        throw new RuntimeException("ImportHandler running twice");
    }
    runState = true;
    try {
        this.viewer = viewer;
        this.qTable = qTable;
        library.addObserver(qTable);
        library.addObserver(viewer);
        library.addObserver(viewer.getErrorHandler());
        library.addObserver(new IObserver() {
            public void update(IObservable importLibrary, ImportEvent event) {
                if (ex.isShutdown()) {
                    log.info("Cancelling import");
                    throw new RuntimeException("CLIENT SHUTDOWN");
                }

            }
        });

        Runnable run = new Runnable() {
            public void run() {
                log.info("Background: Importing images");
                importImages();
            }
        };
        ex.execute(run);
    } finally {
        runState = false; // FIXME this should be set from inside the thread, right?
    }
}

From source file:com.linkedin.d2.balancer.simple.SimpleLoadBalancerTest.java

@Test(groups = { "small", "back-end" })
public void testLoadBalancerSmoke()
        throws URISyntaxException, ServiceUnavailableException, InterruptedException, ExecutionException {
    for (int tryAgain = 0; tryAgain < 1000; ++tryAgain) {
        Map<String, LoadBalancerStrategyFactory<? extends LoadBalancerStrategy>> loadBalancerStrategyFactories = new HashMap<String, LoadBalancerStrategyFactory<? extends LoadBalancerStrategy>>();
        Map<String, TransportClientFactory> clientFactories = new HashMap<String, TransportClientFactory>();
        List<String> prioritizedSchemes = new ArrayList<String>();

        MockStore<ServiceProperties> serviceRegistry = new MockStore<ServiceProperties>();
        MockStore<ClusterProperties> clusterRegistry = new MockStore<ClusterProperties>();
        MockStore<UriProperties> uriRegistry = new MockStore<UriProperties>();

        ScheduledExecutorService executorService = new SynchronousExecutorService();

        //loadBalancerStrategyFactories.put("rr", new RandomLoadBalancerStrategyFactory());
        loadBalancerStrategyFactories.put("degrader", new DegraderLoadBalancerStrategyFactoryV3());
        // PrpcClientFactory();
        clientFactories.put("http", new DoNothingClientFactory()); // new
        // HttpClientFactory();

        SimpleLoadBalancerState state = new SimpleLoadBalancerState(executorService, uriRegistry,
                clusterRegistry, serviceRegistry, clientFactories, loadBalancerStrategyFactories);

        SimpleLoadBalancer loadBalancer = new SimpleLoadBalancer(state, 5, TimeUnit.SECONDS);

        FutureCallback<None> balancerCallback = new FutureCallback<None>();
        loadBalancer.start(balancerCallback);
        balancerCallback.get();//from   w ww .  j a v a 2 s  .  c  o m

        URI uri1 = URI.create("http://test.qa1.com:1234");
        URI uri2 = URI.create("http://test.qa2.com:2345");
        URI uri3 = URI.create("http://test.qa3.com:6789");

        Map<Integer, PartitionData> partitionData = new HashMap<Integer, PartitionData>(1);
        partitionData.put(DefaultPartitionAccessor.DEFAULT_PARTITION_ID, new PartitionData(1d));
        Map<URI, Map<Integer, PartitionData>> uriData = new HashMap<URI, Map<Integer, PartitionData>>(3);
        uriData.put(uri1, partitionData);
        uriData.put(uri2, partitionData);
        uriData.put(uri3, partitionData);

        prioritizedSchemes.add("http");

        clusterRegistry.put("cluster-1", new ClusterProperties("cluster-1"));

        serviceRegistry.put("foo", new ServiceProperties("foo", "cluster-1", "/foo", Arrays.asList("degrader"),
                Collections.<String, Object>emptyMap(), null, null, prioritizedSchemes, null));
        uriRegistry.put("cluster-1", new UriProperties("cluster-1", uriData));

        URI expectedUri1 = URI.create("http://test.qa1.com:1234/foo");
        URI expectedUri2 = URI.create("http://test.qa2.com:2345/foo");
        URI expectedUri3 = URI.create("http://test.qa3.com:6789/foo");

        Set<URI> expectedUris = new HashSet<URI>();

        expectedUris.add(expectedUri1);
        expectedUris.add(expectedUri2);
        expectedUris.add(expectedUri3);

        for (int i = 0; i < 100; ++i) {
            RewriteClient client = (RewriteClient) loadBalancer.getClient(new URIRequest("d2://foo/52"),
                    new RequestContext());

            assertTrue(expectedUris.contains(client.getUri()));
            assertEquals(client.getUri().getScheme(), "http");
        }

        final CountDownLatch latch = new CountDownLatch(1);
        PropertyEventShutdownCallback callback = new PropertyEventShutdownCallback() {
            @Override
            public void done() {
                latch.countDown();
            }
        };

        state.shutdown(callback);

        if (!latch.await(60, TimeUnit.SECONDS)) {
            fail("unable to shutdown state");
        }

        executorService.shutdownNow();

        assertTrue(executorService.isShutdown(), "ExecutorService should have shut down!");
    }
}

From source file:com.linkedin.d2.balancer.simple.SimpleLoadBalancerTest.java

/**
 * This test simulates dropping requests by playing with OverrideDropRate in config
 *
 *///from   w  w  w.j  ava 2  s . c  om
@Test(groups = { "small", "back-end" })
public void testLoadBalancerDropRate()
        throws ServiceUnavailableException, ExecutionException, InterruptedException {
    final int RETRY = 10;
    for (int tryAgain = 0; tryAgain < RETRY; ++tryAgain) {
        Map<String, LoadBalancerStrategyFactory<? extends LoadBalancerStrategy>> loadBalancerStrategyFactories = new HashMap<String, LoadBalancerStrategyFactory<? extends LoadBalancerStrategy>>();
        Map<String, TransportClientFactory> clientFactories = new HashMap<String, TransportClientFactory>();
        List<String> prioritizedSchemes = new ArrayList<String>();

        MockStore<ServiceProperties> serviceRegistry = new MockStore<ServiceProperties>();
        MockStore<ClusterProperties> clusterRegistry = new MockStore<ClusterProperties>();
        MockStore<UriProperties> uriRegistry = new MockStore<UriProperties>();

        ScheduledExecutorService executorService = new SynchronousExecutorService();

        //loadBalancerStrategyFactories.put("rr", new RandomLoadBalancerStrategyFactory());
        loadBalancerStrategyFactories.put("degrader", new DegraderLoadBalancerStrategyFactoryV3());
        // PrpcClientFactory();
        clientFactories.put("http", new DoNothingClientFactory()); // new
        // HttpClientFactory();

        SimpleLoadBalancerState state = new SimpleLoadBalancerState(executorService, uriRegistry,
                clusterRegistry, serviceRegistry, clientFactories, loadBalancerStrategyFactories);

        SimpleLoadBalancer loadBalancer = new SimpleLoadBalancer(state, 5, TimeUnit.SECONDS);

        FutureCallback<None> balancerCallback = new FutureCallback<None>();
        loadBalancer.start(balancerCallback);
        balancerCallback.get();

        URI uri1 = URI.create("http://test.qa1.com:1234");
        URI uri2 = URI.create("http://test.qa2.com:2345");
        URI uri3 = URI.create("http://test.qa3.com:6789");

        Map<Integer, PartitionData> partitionData = new HashMap<Integer, PartitionData>(1);
        partitionData.put(DefaultPartitionAccessor.DEFAULT_PARTITION_ID, new PartitionData(1d));
        Map<URI, Map<Integer, PartitionData>> uriData = new HashMap<URI, Map<Integer, PartitionData>>(3);
        uriData.put(uri1, partitionData);
        uriData.put(uri2, partitionData);
        uriData.put(uri3, partitionData);

        prioritizedSchemes.add("http");

        clusterRegistry.put("cluster-1", new ClusterProperties("cluster-1"));

        serviceRegistry.put("foo", new ServiceProperties("foo", "cluster-1", "/foo", Arrays.asList("degrader"),
                Collections.<String, Object>emptyMap(), null, null, prioritizedSchemes, null));
        uriRegistry.put("cluster-1", new UriProperties("cluster-1", uriData));

        URI expectedUri1 = URI.create("http://test.qa1.com:1234/foo");
        URI expectedUri2 = URI.create("http://test.qa2.com:2345/foo");
        URI expectedUri3 = URI.create("http://test.qa3.com:6789/foo");

        Set<URI> expectedUris = new HashSet<URI>();

        expectedUris.add(expectedUri1);
        expectedUris.add(expectedUri2);
        expectedUris.add(expectedUri3);
        Random random = new Random();

        for (int i = 0; i < 100; ++i) {
            try {
                RewriteClient client = (RewriteClient) loadBalancer.getClient(new URIRequest("d2://foo/52"),
                        new RequestContext());
                TrackerClient tClient = (TrackerClient) client.getWrappedClient();
                DegraderImpl degrader = (DegraderImpl) tClient
                        .getDegrader(DefaultPartitionAccessor.DEFAULT_PARTITION_ID);
                DegraderImpl.Config cfg = new DegraderImpl.Config(degrader.getConfig());
                // Change DropRate to 0.0 at the rate of 1/3
                cfg.setOverrideDropRate((random.nextInt(2) == 0) ? 1.0 : 0.0);
                degrader.setConfig(cfg);

                assertTrue(expectedUris.contains(client.getUri()));
                assertEquals(client.getUri().getScheme(), "http");
            } catch (ServiceUnavailableException e) {
                assertTrue(e.toString().contains("in a bad state (high latency/high error)"));
            }
        }

        final CountDownLatch latch = new CountDownLatch(1);
        PropertyEventShutdownCallback callback = new PropertyEventShutdownCallback() {
            @Override
            public void done() {
                latch.countDown();
            }
        };

        state.shutdown(callback);

        if (!latch.await(60, TimeUnit.SECONDS)) {
            fail("unable to shutdown state");
        }

        executorService.shutdownNow();

        assertTrue(executorService.isShutdown(), "ExecutorService should have shut down!");
    }
}

From source file:com.linkedin.d2.balancer.simple.SimpleLoadBalancerTest.java

@Test(groups = { "small", "back-end" })
public void testLoadBalancerWithPartitionsSmoke()
        throws URISyntaxException, ServiceUnavailableException, InterruptedException, ExecutionException {
    for (int tryAgain = 0; tryAgain < 12; ++tryAgain) {
        Map<String, LoadBalancerStrategyFactory<? extends LoadBalancerStrategy>> loadBalancerStrategyFactories = new HashMap<String, LoadBalancerStrategyFactory<? extends LoadBalancerStrategy>>();
        Map<String, TransportClientFactory> clientFactories = new HashMap<String, TransportClientFactory>();
        List<String> prioritizedSchemes = new ArrayList<String>();

        MockStore<ServiceProperties> serviceRegistry = new MockStore<ServiceProperties>();
        MockStore<ClusterProperties> clusterRegistry = new MockStore<ClusterProperties>();
        MockStore<UriProperties> uriRegistry = new MockStore<UriProperties>();

        ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
        loadBalancerStrategyFactories.put("degrader", new DegraderLoadBalancerStrategyFactoryV3());

        clientFactories.put("http", new DoNothingClientFactory());

        SimpleLoadBalancerState state = new SimpleLoadBalancerState(executorService, uriRegistry,
                clusterRegistry, serviceRegistry, clientFactories, loadBalancerStrategyFactories);

        SimpleLoadBalancer loadBalancer = new SimpleLoadBalancer(state, 5, TimeUnit.SECONDS);

        FutureCallback<None> balancerCallback = new FutureCallback<None>();
        loadBalancer.start(balancerCallback);
        balancerCallback.get();/*from   ww w  . ja va  2 s.c om*/

        URI uri1 = URI.create("http://test.qa1.com:1234");
        URI uri2 = URI.create("http://test.qa2.com:2345");
        URI uri3 = URI.create("http://test.qa3.com:6789");

        Map<URI, Double> uris = new HashMap<URI, Double>();

        uris.put(uri1, 1d);
        uris.put(uri2, 1d);
        uris.put(uri3, 1d);

        Map<URI, Map<Integer, PartitionData>> partitionDesc = new HashMap<URI, Map<Integer, PartitionData>>();

        Map<Integer, PartitionData> server1 = new HashMap<Integer, PartitionData>();
        server1.put(0, new PartitionData(1d));
        server1.put(1, new PartitionData(1d));

        Map<Integer, PartitionData> server2 = new HashMap<Integer, PartitionData>();
        server2.put(0, new PartitionData(1d));

        Map<Integer, PartitionData> server3 = new HashMap<Integer, PartitionData>();
        server3.put(1, new PartitionData(1d));
        partitionDesc.put(uri1, server1);
        partitionDesc.put(uri2, server2);
        partitionDesc.put(uri3, server3);

        prioritizedSchemes.add("http");

        int partitionMethod = tryAgain % 4;
        switch (partitionMethod) {
        case 0:
            clusterRegistry.put("cluster-1",
                    new ClusterProperties("cluster-1", null, new HashMap<String, String>(), new HashSet<URI>(),
                            new RangeBasedPartitionProperties("id=(\\d+)", 0, 50, 2)));
            break;
        case 1:
            clusterRegistry.put("cluster-1",
                    new ClusterProperties("cluster-1", null, new HashMap<String, String>(), new HashSet<URI>(),
                            new HashBasedPartitionProperties("id=(\\d+)", 2,
                                    HashBasedPartitionProperties.HashAlgorithm.valueOf("MODULO"))));
            break;
        case 2:
            clusterRegistry.put("cluster-1",
                    new ClusterProperties("cluster-1", null, new HashMap<String, String>(), new HashSet<URI>(),
                            new HashBasedPartitionProperties("id=(\\d+)", 2,
                                    HashBasedPartitionProperties.HashAlgorithm.valueOf("MD5"))));
            break;
        case 3:
            // test getRings with gap. here, no server serves partition 2
            clusterRegistry.put("cluster-1",
                    new ClusterProperties("cluster-1", null, new HashMap<String, String>(), new HashSet<URI>(),
                            new RangeBasedPartitionProperties("id=(\\d+)", 0, 50, 4)));
            server3.put(3, new PartitionData(1d));
            partitionDesc.put(uri3, server3);
            break;
        default:
            break;
        }

        serviceRegistry.put("foo", new ServiceProperties("foo", "cluster-1", "/foo", Arrays.asList("degrader"),
                Collections.<String, Object>emptyMap(), null, null, prioritizedSchemes, null));

        uriRegistry.put("cluster-1", new UriProperties("cluster-1", partitionDesc));

        if (partitionMethod == 3) {
            Map<Integer, Ring<URI>> ringMap = loadBalancer.getRings(URI.create("d2://foo"));
            assertEquals(ringMap.size(), 4);
            // the ring for partition 2 should be empty
            assertEquals(ringMap.get(2).toString(),
                    new ConsistentHashRing<URI>(Collections.emptyList()).toString());
            continue;
        }

        URI expectedUri1 = URI.create("http://test.qa1.com:1234/foo");
        URI expectedUri2 = URI.create("http://test.qa2.com:2345/foo");
        URI expectedUri3 = URI.create("http://test.qa3.com:6789/foo");

        Set<URI> expectedUris = new HashSet<URI>();
        expectedUris.add(expectedUri1);
        expectedUris.add(expectedUri2);
        expectedUris.add(expectedUri3);

        for (int i = 0; i < 1000; ++i) {
            int ii = i % 100;
            RewriteClient client = (RewriteClient) loadBalancer.getClient(new URIRequest("d2://foo/id=" + ii),
                    new RequestContext());
            String clientUri = client.getUri().toString();
            HashFunction<String[]> hashFunction = null;
            String[] str = new String[1];

            // test KeyMapper target host hint: request is always to target host regardless of what's in d2 URI and whether it's hash-based or range-based partitions
            RequestContext requestContextWithHint = new RequestContext();
            KeyMapper.TargetHostHints.setRequestContextTargetHost(requestContextWithHint, uri1);
            RewriteClient hintedClient1 = (RewriteClient) loadBalancer
                    .getClient(new URIRequest("d2://foo/id=" + ii), requestContextWithHint);
            String hintedUri1 = hintedClient1.getUri().toString();
            Assert.assertEquals(hintedUri1, uri1.toString() + "/foo");
            RewriteClient hintedClient2 = (RewriteClient) loadBalancer
                    .getClient(new URIRequest("d2://foo/action=purge-all"), requestContextWithHint);
            String hintedUri2 = hintedClient2.getUri().toString();
            Assert.assertEquals(hintedUri2, uri1.toString() + "/foo");
            // end test KeyMapper target host hint

            if (partitionMethod == 2) {
                hashFunction = new MD5Hash();
            }
            for (URI uri : expectedUris) {
                if (clientUri.contains(uri.toString())) {
                    // check if only key belonging to partition 0 gets uri2
                    if (uri.equals(uri2)) {
                        if (partitionMethod == 0) {
                            assertTrue(ii < 50);
                        } else if (partitionMethod == 1) {
                            assertTrue(ii % 2 == 0);
                        } else {
                            str[0] = ii + "";
                            assertTrue(hashFunction.hash(str) % 2 == 0);
                        }
                    }
                    // check if only key belonging to partition 1 gets uri3
                    if (uri.equals(uri3)) {
                        if (partitionMethod == 0) {
                            assertTrue(ii >= 50);
                        } else if (partitionMethod == 1) {
                            assertTrue(ii % 2 == 1);
                        } else {
                            str[0] = ii + "";
                            assertTrue(hashFunction.hash(str) % 2 == 1);
                        }
                    }
                }
            }
        }

        // two rings for two partitions
        Map<Integer, Ring<URI>> ringMap = loadBalancer.getRings(URI.create("d2://foo"));
        assertEquals(ringMap.size(), 2);

        if (partitionMethod != 2) {
            Set<String> keys = new HashSet<String>();
            for (int j = 0; j < 50; j++) {
                if (partitionMethod == 0) {
                    keys.add(j + "");
                } else {
                    keys.add(j * 2 + "");
                }
            }

            // if it is range based partition, all keys from 0 ~ 49 belong to partition 0 according to the range definition
            // if it is modulo based partition, all even keys belong to partition 0 because the partition count is 2
            // only from partition 0
            MapKeyResult<Ring<URI>, String> mapKeyResult = loadBalancer.getRings(URI.create("d2://foo"), keys);
            Map<Ring<URI>, Collection<String>> keyToPartition = mapKeyResult.getMapResult();
            assertEquals(keyToPartition.size(), 1);
            for (Ring<URI> ring : keyToPartition.keySet()) {
                assertEquals(ring, ringMap.get(0));
            }

            // now also from partition 1
            keys.add("51");
            mapKeyResult = loadBalancer.getRings(URI.create("d2://foo"), keys);
            assertEquals(mapKeyResult.getMapResult().size(), 2);
            assertEquals(mapKeyResult.getUnmappedKeys().size(), 0);

            // now only from partition 1
            keys.clear();
            keys.add("99");
            mapKeyResult = loadBalancer.getRings(URI.create("d2://foo"), keys);
            keyToPartition = mapKeyResult.getMapResult();
            assertEquals(keyToPartition.size(), 1);
            assertEquals(mapKeyResult.getUnmappedKeys().size(), 0);
            for (Ring<URI> ring : keyToPartition.keySet()) {
                assertEquals(ring, ringMap.get(1));
            }

            keys.add("100");

            mapKeyResult = loadBalancer.getRings(URI.create("d2://foo"), keys);
            if (partitionMethod == 0) {
                // key out of range
                Collection<MapKeyResult.UnmappedKey<String>> unmappedKeys = mapKeyResult.getUnmappedKeys();
                assertEquals(unmappedKeys.size(), 1);
            }

            try {
                loadBalancer.getClient(new URIRequest("d2://foo/id=100"), new RequestContext());
                if (partitionMethod == 0) {
                    // key out of range
                    fail("Should throw ServiceUnavailableException caused by PartitionAccessException");
                }
            } catch (ServiceUnavailableException e) {
            }
        }

        final CountDownLatch latch = new CountDownLatch(1);
        PropertyEventShutdownCallback callback = new PropertyEventShutdownCallback() {
            @Override
            public void done() {
                latch.countDown();
            }
        };

        state.shutdown(callback);

        if (!latch.await(60, TimeUnit.SECONDS)) {
            fail("unable to shutdown state");
        }

        executorService.shutdownNow();

        assertTrue(executorService.isShutdown(), "ExecutorService should have shut down!");
    }
}