Search in sources :

Example 1 with Dispatcher

use of net.dempsy.messages.Dispatcher in project Dempsy by Dempsy.

the class TestElasticity method testNumberCountAddOneThenDrop.

@Test
public void testNumberCountAddOneThenDrop() throws Throwable {
    runCombos("testNumberCountAddOneThenDrop", (r, c, s, t, ser) -> isElasticRoutingStrategy(r), actxPath, ns -> {
        // keepGoing is for the separate thread that pumps messages into the system.
        final AtomicBoolean keepGoing = new AtomicBoolean(true);
        try {
            LOGGER.trace("==== <- Starting");
            final List<NodeManagerWithContext> nodes = new ArrayList<>(ns.nodes);
            // grab the adaptor from the 0'th cluster + the 0'th (only) node.
            final NumberProducer adaptor = nodes.get(0).ctx.getBean(NumberProducer.class);
            // grab access to the Dispatcher from the Adaptor
            final Dispatcher dispatcher = adaptor.dispatcher;
            // This is a Runnable that will pump messages to the dispatcher until keepGoing is
            // flipped to 'false.' It's stateless so it can be reused as needed.
            final AtomicInteger rankIndexToSend = new AtomicInteger(0);
            final Runnable sendMessages = () -> {
                // for an integer is the integer itself so we can get every shard by sending
                while (keepGoing.get()) {
                    for (int num = 0; num < 20; num++) {
                        final int number = num;
                        dispatcher.dispatch(uncheck(() -> ke.extract(new Number(number, rankIndexToSend.get()))));
                    }
                }
            };
            try (final ClusterInfoSession session = ns.sessionFactory.createSession()) {
                waitForEvenShardDistribution(session, "test-cluster1", 3, nodes);
                // Grab the one NumberRank Mp from the single Node in the third (0 base 2nd) cluster.
                final NumberRank rank = nodes.get(4).ctx.getBean(NumberRank.class);
                runACycle(keepGoing, rankIndexToSend.get(), rank, sendMessages);
                // now, bring online another instance.
                LOGGER.trace("==== starting a new one");
                nodes.add(makeNode(new String[] { "elasticity/mp-num-count.xml" }));
                waitForEvenShardDistribution(session, "test-cluster1", 4, nodes);
                // make sure everything still goes through
                runACycle(keepGoing, rankIndexToSend.incrementAndGet(), rank, sendMessages);
                // now kill a node.
                final NodeManagerWithContext nm = nodes.remove(2);
                LOGGER.trace("==== Stopping middle node servicing shards ");
                nm.manager.stop();
                waitForEvenShardDistribution(session, "test-cluster1", 3, nodes);
                LOGGER.trace("==== Stopped middle Dempsy");
                // make sure everything still goes through
                runACycle(keepGoing, rankIndexToSend.incrementAndGet(), rank, sendMessages);
            }
        } finally {
            keepGoing.set(false);
            LOGGER.trace("==== Exiting test.");
        }
    });
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ArrayList(java.util.ArrayList) ClusterInfoSession(net.dempsy.cluster.ClusterInfoSession) Dispatcher(net.dempsy.messages.Dispatcher) Test(org.junit.Test)

Example 2 with Dispatcher

use of net.dempsy.messages.Dispatcher in project Dempsy by Dempsy.

the class TestElasticity method testNumberCountDropOneAndReAdd.

@Test
public void testNumberCountDropOneAndReAdd() throws Throwable {
    runCombos("testNumberCountDropOneAndReAdd", (r, c, s, t, ser) -> isElasticRoutingStrategy(r), actxPath, ns -> {
        // keepGoing is for the separate thread that pumps messages into the system.
        final AtomicBoolean keepGoing = new AtomicBoolean(true);
        try {
            LOGGER.trace("==== <- Starting");
            final List<NodeManagerWithContext> nodes = new ArrayList<>(ns.nodes);
            // grab the adaptor from the 0'th cluster + the 0'th (only) node.
            final NumberProducer adaptor = nodes.get(0).ctx.getBean(NumberProducer.class);
            // grab access to the Dispatcher from the Adaptor
            final Dispatcher dispatcher = adaptor.dispatcher;
            // This is a Runnable that will pump messages to the dispatcher until keepGoing is
            // flipped to 'false.' It's stateless so it can be reused as needed.
            final AtomicInteger rankIndexToSend = new AtomicInteger(0);
            final Runnable sendMessages = () -> {
                // for an integer is the integer itself so we can get every shard by sending
                while (keepGoing.get()) {
                    for (int num = 0; num < 20; num++) {
                        final int number = num;
                        dispatcher.dispatch(uncheck(() -> ke.extract(new Number(number, rankIndexToSend.get()))));
                    }
                }
            };
            try (final ClusterInfoSession session = ns.sessionFactory.createSession()) {
                waitForEvenShardDistribution(session, "test-cluster1", 3, ns.nodes);
                // Grab the one NumberRank Mp from the single Node in the third (0 base 2nd) cluster.
                final NumberRank rank = nodes.get(4).ctx.getBean(NumberRank.class);
                runACycle(keepGoing, rankIndexToSend.get(), rank, sendMessages);
                // now kill a node.
                final NodeManagerWithContext nm = nodes.remove(2);
                LOGGER.trace("==== Stopping middle node servicing shards ");
                nm.manager.stop();
                waitForEvenShardDistribution(session, "test-cluster1", 2, nodes);
                LOGGER.trace("==== Stopped middle Dempsy");
                // make sure everything still goes through
                runACycle(keepGoing, rankIndexToSend.incrementAndGet(), rank, sendMessages);
                // now, bring online another instance.
                LOGGER.trace("==== starting a new one");
                nodes.add(makeNode(new String[] { "elasticity/mp-num-count.xml" }));
                waitForEvenShardDistribution(session, "test-cluster1", 3, nodes);
                // make sure everything still goes through
                runACycle(keepGoing, rankIndexToSend.incrementAndGet(), rank, sendMessages);
            }
        } finally {
            keepGoing.set(false);
            LOGGER.trace("==== Exiting test.");
        }
    });
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ArrayList(java.util.ArrayList) ClusterInfoSession(net.dempsy.cluster.ClusterInfoSession) Dispatcher(net.dempsy.messages.Dispatcher) Test(org.junit.Test)

Example 3 with Dispatcher

use of net.dempsy.messages.Dispatcher in project Dempsy by Dempsy.

the class TestElasticity method testExpansionPassivation.

@Test
public void testExpansionPassivation() throws Exception {
    final String[][] actxPath = { { "elasticity/adaptor.xml" }, { "elasticity/mp-num-count.xml" }, { "elasticity/mp-num-rank.xml" } };
    runCombos("testExpansionPassivation", (r, c, s, t, ser) -> isElasticRoutingStrategy(r), actxPath, ns -> {
        final AtomicBoolean keepGoing = new AtomicBoolean(true);
        try {
            final List<NodeManagerWithContext> nodes = new ArrayList<>(ns.nodes);
            // grab the adaptor from the 0'th cluster + the 0'th (only) node.
            final NumberProducer adaptor = nodes.get(0).ctx.getBean(NumberProducer.class);
            // grab access to the Dispatcher from the Adaptor
            final Dispatcher dispatcher = adaptor.dispatcher;
            final AtomicInteger rankIndexToSend = new AtomicInteger(0);
            final Runnable sendMessages = () -> {
                // for an integer is the integer itself so we can get every shard by sending
                while (keepGoing.get()) {
                    for (int num = 0; num < 20; num++) {
                        final int number = num;
                        dispatcher.dispatch(uncheck(() -> ke.extract(new Number(number, rankIndexToSend.get()))));
                    }
                }
            };
            try (final ClusterInfoSession session = ns.sessionFactory.createSession()) {
                waitForEvenShardDistribution(session, "test-cluster1", 1, nodes);
                final NumberRank rank = nodes.get(2).ctx.getBean(NumberRank.class);
                runACycle(keepGoing, rankIndexToSend.get(), rank, sendMessages);
                // now we have 20 Mps in test-cluster1
                final ClusterMetricGetters sc = (ClusterMetricGetters) nodes.get(1).manager.getClusterStatsCollector(new ClusterId(currentAppName, "test-cluster1"));
                assertEquals(20L, sc.getMessageProcessorCount());
                // add a second node for the cluster test-cluster1
                nodes.add(makeNode(new String[] { "elasticity/mp-num-count.xml" }));
                waitForEvenShardDistribution(session, "test-cluster1", 2, nodes);
                // about 1/2 should drop out.
                assertTrue(poll(o -> {
                    // System.err.println(sc.getMessageProcessorCount());
                    return sc.getMessageProcessorCount() < 15L;
                }));
            }
        } finally {
            keepGoing.set(false);
        }
    });
}
Also used : IntStream(java.util.stream.IntStream) MessageProcessor(net.dempsy.lifecycle.annotation.MessageProcessor) Mp(net.dempsy.lifecycle.annotation.Mp) ClusterInfoSession(net.dempsy.cluster.ClusterInfoSession) MessageType(net.dempsy.lifecycle.annotation.MessageType) Dispatcher(net.dempsy.messages.Dispatcher) NodeAddress(net.dempsy.transport.NodeAddress) LoggerFactory(org.slf4j.LoggerFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Random(java.util.Random) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) ArrayList(java.util.ArrayList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) ThreadingModel(net.dempsy.threading.ThreadingModel) ClusterId(net.dempsy.config.ClusterId) MessageKey(net.dempsy.lifecycle.annotation.MessageKey) Logger(org.slf4j.Logger) NodeMetricGetters(net.dempsy.container.NodeMetricGetters) MessageHandler(net.dempsy.lifecycle.annotation.MessageHandler) Functional.uncheck(net.dempsy.util.Functional.uncheck) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ClusterMetricGetters(net.dempsy.container.ClusterMetricGetters) Assert.assertTrue(org.junit.Assert.assertTrue) Set(java.util.Set) Test(org.junit.Test) Activation(net.dempsy.lifecycle.annotation.Activation) KeyExtractor(net.dempsy.lifecycle.annotation.utils.KeyExtractor) Collectors(java.util.stream.Collectors) Serializable(java.io.Serializable) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) Adaptor(net.dempsy.messages.Adaptor) ConditionPoll.poll(net.dempsy.utils.test.ConditionPoll.poll) Functional.chain(net.dempsy.util.Functional.chain) ConditionPoll.assertTrue(net.dempsy.utils.test.ConditionPoll.assertTrue) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) ClusterId(net.dempsy.config.ClusterId) ArrayList(java.util.ArrayList) Dispatcher(net.dempsy.messages.Dispatcher) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ClusterMetricGetters(net.dempsy.container.ClusterMetricGetters) ClusterInfoSession(net.dempsy.cluster.ClusterInfoSession) Test(org.junit.Test)

Example 4 with Dispatcher

use of net.dempsy.messages.Dispatcher in project Dempsy by Dempsy.

the class TestElasticity method testForProfiler.

@Test
public void testForProfiler() throws Throwable {
    try {
        // set up the test.
        final Number[] numbers = new Number[profilerTestNumberCount];
        final Random random = new Random();
        for (int i = 0; i < numbers.length; i++) numbers[i] = new Number(random.nextInt(1000), 0);
        final KeyExtractor ke = new KeyExtractor();
        runCombos("testForProfiler", (r, c, s, t, ser) -> isElasticRoutingStrategy(r), actxPath, new String[][][] { null, { { "min_nodes", "3" } }, { { "min_nodes", "3" } }, { { "min_nodes", "3" } }, null }, ns -> {
            final List<NodeManagerWithContext> nodes = ns.nodes;
            // Grab the one NumberRank Mp from the single Node in the third (0 base 2nd) cluster.
            final NumberRank rank = nodes.get(4).ctx.getBean(NumberRank.class);
            try (final ClusterInfoSession session = ns.sessionFactory.createSession()) {
                waitForEvenShardDistribution(session, "test-cluster1", 3, nodes);
                // get the Adaptor Router's statCollector
                final List<NodeMetricGetters> scs = nodes.stream().map(nwm -> nwm.manager).map(nm -> nm.getNodeStatsCollector()).map(sc -> (NodeMetricGetters) sc).collect(Collectors.toList());
                // grab the adaptor from the 0'th cluster + the 0'th (only) node.
                final NumberProducer adaptor = nodes.get(0).ctx.getBean(NumberProducer.class);
                // grab access to the Dispatcher from the Adaptor
                final Dispatcher dispatcher = adaptor.dispatcher;
                final long startTime = System.currentTimeMillis();
                for (int i = 0; i < numbers.length; i++) dispatcher.dispatch(ke.extract(numbers[i]));
                LOGGER.info("====> Checking exact count.");
                // keep going as long as they are trickling in.
                assertTrue(() -> {
                    IntStream.range(0, scs.size()).forEach(i -> {
                        System.out.println("======> " + i);
                        final NodeMetricGetters mg = scs.get(i);
                        if (mg != null) {
                            System.out.println("discarded: " + mg.getDiscardedMessageCount());
                            System.out.println("not sent: " + mg.getMessagesNotSentCount());
                        }
                    });
                    return "expected: " + profilerTestNumberCount + " but was: " + (rank.totalMessages.get() + scs.get(0).getMessagesNotSentCount()) + ", (delivered: " + rank.totalMessages.get() + ", not sent: " + scs.get(0).getMessagesNotSentCount() + ")";
                }, poll(o -> profilerTestNumberCount == (rank.totalMessages.get() + scs.stream().map(sc -> new Long(sc.getMessagesNotSentCount())).reduce(new Long(0), (v1, v2) -> new Long(v1.longValue() + v2.longValue()).longValue()))));
                // assert that at least SOMETHING went through
                assertTrue(rank.totalMessages.get() > 0);
                LOGGER.info("testForProfiler time " + (System.currentTimeMillis() - startTime));
                @SuppressWarnings("unchecked") final AtomicLong count = nodes.stream().map(// get the NumberCounter Mp
                nmwc -> (MessageProcessor<NumberCounter>) nmwc.manager.getMp("test-cluster1")).filter(// if it exists
                l -> l != null).map(// pull the prototype
                l -> l.getPrototype().messageCount).reduce(new AtomicLong(0), // sum up all of the counts
                (v1, v2) -> new AtomicLong(v1.get() + v2.get()));
                assertEquals(profilerTestNumberCount, count.get());
            }
        });
    } catch (final Throwable th) {
        th.printStackTrace();
        throw th;
    }
}
Also used : IntStream(java.util.stream.IntStream) MessageProcessor(net.dempsy.lifecycle.annotation.MessageProcessor) Mp(net.dempsy.lifecycle.annotation.Mp) ClusterInfoSession(net.dempsy.cluster.ClusterInfoSession) MessageType(net.dempsy.lifecycle.annotation.MessageType) Dispatcher(net.dempsy.messages.Dispatcher) NodeAddress(net.dempsy.transport.NodeAddress) LoggerFactory(org.slf4j.LoggerFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Random(java.util.Random) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) ArrayList(java.util.ArrayList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) ThreadingModel(net.dempsy.threading.ThreadingModel) ClusterId(net.dempsy.config.ClusterId) MessageKey(net.dempsy.lifecycle.annotation.MessageKey) Logger(org.slf4j.Logger) NodeMetricGetters(net.dempsy.container.NodeMetricGetters) MessageHandler(net.dempsy.lifecycle.annotation.MessageHandler) Functional.uncheck(net.dempsy.util.Functional.uncheck) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ClusterMetricGetters(net.dempsy.container.ClusterMetricGetters) Assert.assertTrue(org.junit.Assert.assertTrue) Set(java.util.Set) Test(org.junit.Test) Activation(net.dempsy.lifecycle.annotation.Activation) KeyExtractor(net.dempsy.lifecycle.annotation.utils.KeyExtractor) Collectors(java.util.stream.Collectors) Serializable(java.io.Serializable) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) Adaptor(net.dempsy.messages.Adaptor) ConditionPoll.poll(net.dempsy.utils.test.ConditionPoll.poll) Functional.chain(net.dempsy.util.Functional.chain) ConditionPoll.assertTrue(net.dempsy.utils.test.ConditionPoll.assertTrue) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) MessageProcessor(net.dempsy.lifecycle.annotation.MessageProcessor) NodeMetricGetters(net.dempsy.container.NodeMetricGetters) Dispatcher(net.dempsy.messages.Dispatcher) AtomicLong(java.util.concurrent.atomic.AtomicLong) Random(java.util.Random) AtomicLong(java.util.concurrent.atomic.AtomicLong) KeyExtractor(net.dempsy.lifecycle.annotation.utils.KeyExtractor) ClusterInfoSession(net.dempsy.cluster.ClusterInfoSession) Test(org.junit.Test)

Aggregations

ArrayList (java.util.ArrayList)4 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 ClusterInfoSession (net.dempsy.cluster.ClusterInfoSession)4 Dispatcher (net.dempsy.messages.Dispatcher)4 Test (org.junit.Test)4 Serializable (java.io.Serializable)2 Collections (java.util.Collections)2 List (java.util.List)2 Map (java.util.Map)2 Random (java.util.Random)2 Set (java.util.Set)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 Function (java.util.function.Function)2 Collectors (java.util.stream.Collectors)2 IntStream (java.util.stream.IntStream)2 ClusterId (net.dempsy.config.ClusterId)2 ClusterMetricGetters (net.dempsy.container.ClusterMetricGetters)2