Search in sources :

Example 11 with ClusterId

use of net.dempsy.config.ClusterId in project Dempsy by Dempsy.

the class TestInstanceManager method setupContainer.

@SuppressWarnings("resource")
public Container setupContainer(final MessageProcessorLifecycle<?> prototype) throws ContainerException {
    dispatcher = new DummyDispatcher();
    statsCollector = new BasicClusterStatsCollector();
    manager = new NonLockingAltContainer().setMessageProcessor(prototype).setClusterId(new ClusterId("test", "test"));
    manager.setDispatcher(dispatcher);
    manager.setInbound(new DummyInbound());
    tm = new DefaultThreadingModel(TestInstanceManager.class.getName());
    tm.start(TestInstanceManager.class.getName());
    manager.start(new TestInfrastructure(tm) {

        BasicNodeStatsCollector nStats = new BasicNodeStatsCollector();

        @Override
        public ClusterStatsCollector getClusterStatsCollector(final ClusterId clusterId) {
            return statsCollector;
        }

        @Override
        public NodeStatsCollector getNodeStatsCollector() {
            return nStats;
        }
    });
    return manager;
}
Also used : DummyInbound(net.dempsy.container.mocks.DummyInbound) BasicNodeStatsCollector(net.dempsy.monitoring.basic.BasicNodeStatsCollector) NodeStatsCollector(net.dempsy.monitoring.NodeStatsCollector) TestInfrastructure(net.dempsy.util.TestInfrastructure) BasicClusterStatsCollector(net.dempsy.monitoring.basic.BasicClusterStatsCollector) ClusterStatsCollector(net.dempsy.monitoring.ClusterStatsCollector) ClusterId(net.dempsy.config.ClusterId) BasicClusterStatsCollector(net.dempsy.monitoring.basic.BasicClusterStatsCollector) DefaultThreadingModel(net.dempsy.threading.DefaultThreadingModel) NonLockingAltContainer(net.dempsy.container.altnonlocking.NonLockingAltContainer) BasicNodeStatsCollector(net.dempsy.monitoring.basic.BasicNodeStatsCollector)

Example 12 with ClusterId

use of net.dempsy.config.ClusterId in project Dempsy by Dempsy.

the class TestGroupRoutingStrategy method testInboundDoubleHappyPathRegister.

@Test
public void testInboundDoubleHappyPathRegister() throws Exception {
    final int numShardsToExpect = Integer.parseInt(Utils.DEFAULT_TOTAL_SHARDS);
    final String groupName = "testInboundDoubleHappyPathRegister";
    try (final RoutingStrategy.Inbound ib1 = new RoutingInboundManager().getAssociatedInstance(ClusterGroupInbound.class.getPackage().getName() + ":" + groupName);
        final RoutingStrategy.Inbound ib2 = new RoutingInboundManager().getAssociatedInstance(ClusterGroupInbound.class.getPackage().getName() + ":" + groupName)) {
        final ClusterId clusterId = new ClusterId("test", "test");
        final NodeAddress node1Addr = new DummyNodeAddress("node1");
        final GroupDetails gd1 = new GroupDetails(groupName, node1Addr);
        final ContainerAddress node1Ca = new ContainerAddress(node1Addr, 0);
        final Utils<GroupDetails> utils = new Utils<>(infra, groupName, gd1);
        ib1.setContainerDetails(clusterId, node1Ca, (l, m) -> {
        });
        ib1.start(infra);
        final NodeAddress node2Addr = new DummyNodeAddress("node2");
        final ContainerAddress node2Ca = new ContainerAddress(node2Addr, 0);
        ib2.setContainerDetails(clusterId, node2Ca, (l, m) -> {
        });
        try (final ClusterInfoSession session2 = sessFact.createSession()) {
            ib2.start(new TestInfrastructure(session2, infra.getScheduler()));
            assertTrue(waitForShards(session, utils, numShardsToExpect));
            // if this worked right then numShardsToExpect/2 should be owned by each ... eventually.
            checkForShardDistribution(session, utils, numShardsToExpect, 2);
            // disrupt the session. This should cause a reshuffle but not fail
            disruptor.accept(session2);
            // everything should settle back
            checkForShardDistribution(session, utils, numShardsToExpect, 2);
            // now kill the second session.
            // this will disconnect the second Inbound and so the first should take over
            session2.close();
            // see if we now have 1 session and it has all shards
            checkForShardDistribution(session, utils, numShardsToExpect, 1);
        }
    }
}
Also used : TestInfrastructure(net.dempsy.util.TestInfrastructure) ClusterId(net.dempsy.config.ClusterId) ContainerAddress(net.dempsy.router.RoutingStrategy.ContainerAddress) RoutingInboundManager(net.dempsy.router.RoutingInboundManager) GroupDetails(net.dempsy.router.group.intern.GroupDetails) Utils(net.dempsy.router.shardutils.Utils) RoutingStrategy(net.dempsy.router.RoutingStrategy) NodeAddress(net.dempsy.transport.NodeAddress) ClusterInfoSession(net.dempsy.cluster.ClusterInfoSession) Test(org.junit.Test)

Example 13 with ClusterId

use of net.dempsy.config.ClusterId in project Dempsy by Dempsy.

the class TestContainerLoadHandling method setUp.

@Before
public void setUp() throws Exception {
    final ClusterId cid = new ClusterId("TestContainerLoadHandling", "test" + sequence++);
    dispatcher = new MockDispatcher();
    final BasicClusterStatsCollector sc = new BasicClusterStatsCollector();
    clusterStats = sc;
    nodeStats = new BasicNodeStatsCollector();
    container = tr.track(new Manager<Container>(Container.class).getAssociatedInstance(containerId)).setMessageProcessor(new MessageProcessor<TestMessageProcessor>(new TestMessageProcessor())).setClusterId(cid);
    container.setDispatcher(dispatcher);
    container.setInbound(new DummyInbound());
    container.start(new TestInfrastructure(null, null) {

        @Override
        public ClusterStatsCollector getClusterStatsCollector(final ClusterId clusterId) {
            return sc;
        }

        @Override
        public NodeStatsCollector getNodeStatsCollector() {
            return nodeStats;
        }
    });
    forceOutputException = false;
    stillRunning = true;
}
Also used : BasicNodeStatsCollector(net.dempsy.monitoring.basic.BasicNodeStatsCollector) NodeStatsCollector(net.dempsy.monitoring.NodeStatsCollector) TestInfrastructure(net.dempsy.util.TestInfrastructure) ClusterId(net.dempsy.config.ClusterId) BasicClusterStatsCollector(net.dempsy.monitoring.basic.BasicClusterStatsCollector) DummyInbound(net.dempsy.container.mocks.DummyInbound) NonLockingAltContainer(net.dempsy.container.altnonlocking.NonLockingAltContainer) LockingContainer(net.dempsy.container.locking.LockingContainer) BasicClusterStatsCollector(net.dempsy.monitoring.basic.BasicClusterStatsCollector) ClusterStatsCollector(net.dempsy.monitoring.ClusterStatsCollector) BasicNodeStatsCollector(net.dempsy.monitoring.basic.BasicNodeStatsCollector) Before(org.junit.Before)

Example 14 with ClusterId

use of net.dempsy.config.ClusterId in project Dempsy by Dempsy.

the class NodeManager method start.

public NodeManager start() throws DempsyException {
    validate();
    nodeStatsCollector = tr.track((NodeStatsCollector) node.getNodeStatsCollector());
    // TODO: cleaner?
    statsCollectorFactory = tr.track(new Manager<>(ClusterStatsCollectorFactory.class).getAssociatedInstance(node.getClusterStatsCollectorFactoryId()));
    // =====================================
    // set the dispatcher on adaptors and create containers for mp clusters
    final AtomicReference<String> firstAdaptorClusterName = new AtomicReference<>(null);
    node.getClusters().forEach(c -> {
        if (c.isAdaptor()) {
            if (firstAdaptorClusterName.get() == null)
                firstAdaptorClusterName.set(c.getClusterId().clusterName);
            final Adaptor adaptor = c.getAdaptor();
            adaptors.put(c.getClusterId(), adaptor);
            if (c.getRoutingStrategyId() != null && !"".equals(c.getRoutingStrategyId().trim()) && !" ".equals(c.getRoutingStrategyId().trim()))
                LOGGER.warn("The cluster " + c.getClusterId() + " contains an adaptor but also has the routingStrategy set. The routingStrategy will be ignored.");
            if (c.getOutputScheduler() != null)
                LOGGER.warn("The cluster " + c.getClusterId() + " contains an adaptor but also has an output executor set. The output executor will never be used.");
        } else {
            String containerTypeId = c.getContainerTypeId();
            if (containerTypeId == null)
                // can't be null
                containerTypeId = node.getContainerTypeId();
            final Container con = makeContainer(containerTypeId).setMessageProcessor(c.getMessageProcessor()).setClusterId(c.getClusterId()).setMaxPendingMessagesPerContainer(c.getMaxPendingMessagesPerContainer());
            // TODO: This is a hack for now.
            final Manager<RoutingStrategy.Inbound> inboundManager = new RoutingInboundManager();
            final RoutingStrategy.Inbound is = inboundManager.getAssociatedInstance(c.getRoutingStrategyId());
            final boolean outputSupported = c.getMessageProcessor().isOutputSupported();
            final Object outputScheduler = c.getOutputScheduler();
            // if there mp handles output but there's no output scheduler then we should warn.
            if (outputSupported && outputScheduler == null)
                LOGGER.warn("The cluster " + c.getClusterId() + " contains a message processor that supports an output cycle but there's no executor set so it will never be invoked.");
            if (!outputSupported && outputScheduler != null)
                LOGGER.warn("The cluster " + c.getClusterId() + " contains a message processor that doesn't support an output cycle but there's an output cycle executor set. The output cycle executor will never be used.");
            final OutputScheduler os = (outputSupported && outputScheduler != null) ? (OutputScheduler) outputScheduler : null;
            containers.add(new PerContainer(con, is, c, os));
        }
    });
    // it we're all adaptor then don't bother to get the receiver.
    if (containers.size() == 0) {
        // here there's no point in a receiver since there's nothing to receive.
        if (firstAdaptorClusterName.get() == null)
            throw new IllegalStateException("There seems to be no clusters or adaptors defined for this node \"" + node.toString() + "\"");
    } else {
        receiver = (Receiver) node.getReceiver();
        if (// otherwise we're all adaptor
        receiver != null)
            nodeAddress = receiver.getAddress(this);
        else if (firstAdaptorClusterName.get() == null)
            throw new IllegalStateException("There seems to be no clusters or adaptors defined for this node \"" + node.toString() + "\"");
    }
    nodeId = Optional.ofNullable(nodeAddress).map(n -> n.getGuid()).orElse(firstAdaptorClusterName.get());
    if (nodeStatsCollector == null) {
        LOGGER.warn("There is no {} set for the the application '{}'", StatsCollector.class.getSimpleName(), node.application);
        nodeStatsCollector = new DummyNodeStatsCollector();
    }
    nodeStatsCollector.setNodeId(nodeId);
    if (nodeAddress == null && node.getReceiver() != null)
        LOGGER.warn("The node at " + nodeId + " contains no message processors but has a Reciever set. The receiver will never be started.");
    if (nodeAddress == null && node.getDefaultRoutingStrategyId() != null)
        LOGGER.warn("The node at " + nodeId + " contains no message processors but has a defaultRoutingStrategyId set. The routingStrategyId will never be used.");
    if (threading == null)
        threading = tr.track(new DefaultThreadingModel(nodeId)).configure(node.getConfiguration()).start(nodeId);
    else if (!threading.isStarted())
        threading.start(nodeId);
    nodeStatsCollector.setMessagesPendingGauge(() -> threading.getNumberLimitedPending());
    final NodeReceiver nodeReciever = receiver == null ? null : tr.track(new NodeReceiver(containers.stream().map(pc -> pc.container).collect(Collectors.toList()), threading, nodeStatsCollector));
    final Map<ClusterId, ClusterInformation> messageTypesByClusterId = new HashMap<>();
    containers.stream().map(pc -> pc.clusterDefinition).forEach(c -> {
        messageTypesByClusterId.put(c.getClusterId(), new ClusterInformation(c.getRoutingStrategyId(), c.getClusterId(), c.getMessageProcessor().messagesTypesHandled()));
    });
    final NodeInformation nodeInfo = nodeAddress != null ? new NodeInformation(receiver.transportTypeId(), nodeAddress, messageTypesByClusterId) : null;
    // Then actually register the Node
    if (nodeInfo != null) {
        keepNodeRegstered = new PersistentTask(LOGGER, isRunning, persistenceScheduler, RETRY_PERIOND_MILLIS) {

            @Override
            public boolean execute() {
                try {
                    session.recursiveMkdir(rootPaths.clustersDir, null, DirMode.PERSISTENT, DirMode.PERSISTENT);
                    session.recursiveMkdir(rootPaths.nodesDir, null, DirMode.PERSISTENT, DirMode.PERSISTENT);
                    final String nodePath = rootPaths.nodesDir + "/" + nodeId;
                    session.mkdir(nodePath, nodeInfo, DirMode.EPHEMERAL);
                    final NodeInformation reread = (NodeInformation) session.getData(nodePath, this);
                    final boolean ret = nodeInfo.equals(reread);
                    if (ret == true)
                        ptaskReady.set(true);
                    return ret;
                } catch (final ClusterInfoException e) {
                    final String logmessage = "Failed to register the node. Retrying in " + RETRY_PERIOND_MILLIS + " milliseconds.";
                    if (LOGGER.isDebugEnabled())
                        LOGGER.info(logmessage, e);
                    else
                        LOGGER.info(logmessage, e);
                }
                return false;
            }

            @Override
            public String toString() {
                return "register node information";
            }
        };
    }
    // =====================================
    // The layering works this way.
    // 
    // Receiver -> NodeReceiver -> adaptor -> container -> OutgoingDispatcher -> RoutingStrategyOB -> Transport
    // 
    // starting needs to happen in reverse.
    // =====================================
    isRunning.set(true);
    this.tManager = tr.start(new TransportManager(), this);
    this.rsManager = tr.start(new RoutingStrategyManager(), this);
    // create the router but don't start it yet.
    this.router = new OutgoingDispatcher(rsManager, nodeAddress, nodeId, nodeReciever, tManager, nodeStatsCollector);
    // set up containers
    containers.forEach(pc -> pc.container.setDispatcher(router).setEvictionCycle(pc.clusterDefinition.getEvictionFrequency().evictionFrequency, pc.clusterDefinition.getEvictionFrequency().evictionTimeUnit));
    // IB routing strategy
    final int numContainers = containers.size();
    for (int i = 0; i < numContainers; i++) {
        final PerContainer c = containers.get(i);
        c.inboundStrategy.setContainerDetails(c.clusterDefinition.getClusterId(), new ContainerAddress(nodeAddress, i), c.container);
    }
    // setup the output executors by passing the containers
    containers.stream().filter(pc -> pc.outputScheduler != null).forEach(pc -> pc.outputScheduler.setOutputInvoker(pc.container));
    // set up adaptors
    adaptors.values().forEach(a -> a.setDispatcher(router));
    // start containers after setting inbound
    containers.forEach(pc -> tr.start(pc.container.setInbound(pc.inboundStrategy), this));
    // start the output schedulers now that the containers have been started.
    containers.stream().map(pc -> pc.outputScheduler).filter(os -> os != null).forEach(os -> tr.start(os, this));
    // start IB routing strategy
    containers.forEach(pc -> tr.start(pc.inboundStrategy, this));
    // start router
    tr.start(this.router, this);
    final PersistentTask startAdaptorAfterRouterIsRunning = new PersistentTask(LOGGER, isRunning, this.persistenceScheduler, 500) {

        @Override
        public boolean execute() {
            if (!router.isReady())
                return false;
            adaptors.entrySet().forEach(e -> threading.runDaemon(() -> tr.track(e.getValue()).start(), "Adaptor-" + e.getKey().clusterName));
            return true;
        }
    };
    // make sure the router is running. Once it is, start the adaptor(s)
    startAdaptorAfterRouterIsRunning.process();
    if (receiver != null)
        tr.track(receiver).start(nodeReciever, this);
    // close this session when we're done.
    tr.track(session);
    // make it known we're here and ready
    if (keepNodeRegstered != null)
        keepNodeRegstered.process();
    else
        ptaskReady.set(true);
    return this;
}
Also used : Adaptor(net.dempsy.messages.Adaptor) ClusterInfoException(net.dempsy.cluster.ClusterInfoException) TransportManager(net.dempsy.transport.TransportManager) ClusterInfoSession(net.dempsy.cluster.ClusterInfoSession) Node(net.dempsy.config.Node) ContainerAddress(net.dempsy.router.RoutingStrategy.ContainerAddress) DefaultThreadingModel(net.dempsy.threading.DefaultThreadingModel) NodeAddress(net.dempsy.transport.NodeAddress) LoggerFactory(org.slf4j.LoggerFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) DirMode(net.dempsy.cluster.DirMode) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) OutputScheduler(net.dempsy.output.OutputScheduler) RoutingStrategyManager(net.dempsy.router.RoutingStrategyManager) Functional.ignore(net.dempsy.util.Functional.ignore) RoutingStrategy(net.dempsy.router.RoutingStrategy) Map(java.util.Map) ThreadingModel(net.dempsy.threading.ThreadingModel) RoutingInboundManager(net.dempsy.router.RoutingInboundManager) Receiver(net.dempsy.transport.Receiver) ClusterId(net.dempsy.config.ClusterId) StatsCollector(net.dempsy.monitoring.StatsCollector) Cluster(net.dempsy.config.Cluster) ClusterStatsCollectorFactory(net.dempsy.monitoring.ClusterStatsCollectorFactory) DummyNodeStatsCollector(net.dempsy.monitoring.dummy.DummyNodeStatsCollector) Logger(org.slf4j.Logger) SafeString(net.dempsy.util.SafeString) ClusterInfoSessionFactory(net.dempsy.cluster.ClusterInfoSessionFactory) Collection(java.util.Collection) OutgoingDispatcher(net.dempsy.intern.OutgoingDispatcher) Collectors(java.util.stream.Collectors) AutoDisposeSingleThreadScheduler(net.dempsy.util.executor.AutoDisposeSingleThreadScheduler) TimeUnit(java.util.concurrent.TimeUnit) ClusterStatsCollector(net.dempsy.monitoring.ClusterStatsCollector) NodeStatsCollector(net.dempsy.monitoring.NodeStatsCollector) List(java.util.List) Adaptor(net.dempsy.messages.Adaptor) PersistentTask(net.dempsy.utils.PersistentTask) Optional(java.util.Optional) Container(net.dempsy.container.Container) Inbound(net.dempsy.router.RoutingStrategy.Inbound) MessageProcessorLifecycle(net.dempsy.messages.MessageProcessorLifecycle) Collections(java.util.Collections) RoutingStrategyManager(net.dempsy.router.RoutingStrategyManager) HashMap(java.util.HashMap) OutgoingDispatcher(net.dempsy.intern.OutgoingDispatcher) ClusterInfoException(net.dempsy.cluster.ClusterInfoException) SafeString(net.dempsy.util.SafeString) Inbound(net.dempsy.router.RoutingStrategy.Inbound) PersistentTask(net.dempsy.utils.PersistentTask) OutputScheduler(net.dempsy.output.OutputScheduler) RoutingInboundManager(net.dempsy.router.RoutingInboundManager) Container(net.dempsy.container.Container) DummyNodeStatsCollector(net.dempsy.monitoring.dummy.DummyNodeStatsCollector) RoutingStrategy(net.dempsy.router.RoutingStrategy) DummyNodeStatsCollector(net.dempsy.monitoring.dummy.DummyNodeStatsCollector) NodeStatsCollector(net.dempsy.monitoring.NodeStatsCollector) StatsCollector(net.dempsy.monitoring.StatsCollector) DummyNodeStatsCollector(net.dempsy.monitoring.dummy.DummyNodeStatsCollector) ClusterStatsCollector(net.dempsy.monitoring.ClusterStatsCollector) NodeStatsCollector(net.dempsy.monitoring.NodeStatsCollector) ClusterId(net.dempsy.config.ClusterId) AtomicReference(java.util.concurrent.atomic.AtomicReference) Inbound(net.dempsy.router.RoutingStrategy.Inbound) DefaultThreadingModel(net.dempsy.threading.DefaultThreadingModel) ContainerAddress(net.dempsy.router.RoutingStrategy.ContainerAddress) ClusterStatsCollectorFactory(net.dempsy.monitoring.ClusterStatsCollectorFactory) TransportManager(net.dempsy.transport.TransportManager)

Example 15 with ClusterId

use of net.dempsy.config.ClusterId in project Dempsy by Dempsy.

the class MessageProcessor method checkOrInvokeValidStartMethod.

// ----------------------------------------------------------------------------
// Internals
// ----------------------------------------------------------------------------
private void checkOrInvokeValidStartMethod(final boolean invoke, final ClusterId clusterId) throws IllegalStateException {
    Method startMethod = null;
    for (final Method method : prototype.getClass().getMethods()) {
        if (method.isAnnotationPresent(Start.class)) {
            if (startMethod != null)
                throw new IllegalStateException("Multiple methods on the message processor of type\"" + SafeString.valueOf(prototype) + "\" is identified as a Start method. Please annotate at most one method using @Start.");
            startMethod = method;
        }
    }
    // if the start method takes a ClusterId or ClusterDefinition then pass it.
    if (startMethod != null) {
        final Class<?>[] parameterTypes = startMethod.getParameterTypes();
        boolean takesClusterId = false;
        if (parameterTypes != null && parameterTypes.length == 1) {
            if (ClusterId.class.isAssignableFrom(parameterTypes[0]))
                takesClusterId = true;
            else {
                throw new IllegalStateException("The method \"" + startMethod.getName() + "\" on " + SafeString.objectDescription(prototype) + " is annotated with the @" + Start.class.getSimpleName() + " annotation but doesn't have the correct signature. " + "It needs to either take no parameters or take a single " + ClusterId.class.getSimpleName() + " parameter.");
            }
        } else if (parameterTypes != null && parameterTypes.length > 1) {
            throw new IllegalStateException("The method \"" + startMethod.getName() + "\" on " + SafeString.objectDescription(prototype) + " is annotated with the @" + Start.class.getSimpleName() + " annotation but doesn't have the correct signature. " + "It needs to either take no parameters or take a single " + ClusterId.class.getSimpleName() + " parameter.");
        }
        if (invoke) {
            try {
                if (takesClusterId)
                    startMethod.invoke(prototype, clusterId);
                else
                    startMethod.invoke(prototype);
            } catch (final Exception e) {
                LOGGER.error(MarkerFactory.getMarker("FATAL"), "can't run MP initializer " + startMethod.getName(), e);
            }
        }
    }
}
Also used : ClusterId(net.dempsy.config.ClusterId) Method(java.lang.reflect.Method) DempsyException(net.dempsy.DempsyException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Aggregations

ClusterId (net.dempsy.config.ClusterId)30 Test (org.junit.Test)24 ContainerAddress (net.dempsy.router.RoutingStrategy.ContainerAddress)16 List (java.util.List)15 ConditionPoll.poll (net.dempsy.utils.test.ConditionPoll.poll)15 Assert.assertEquals (org.junit.Assert.assertEquals)15 Assert.assertTrue (org.junit.Assert.assertTrue)15 Logger (org.slf4j.Logger)14 LoggerFactory (org.slf4j.LoggerFactory)14 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)13 ArrayList (java.util.ArrayList)12 RoutingStrategy (net.dempsy.router.RoutingStrategy)12 ClusterInfoSession (net.dempsy.cluster.ClusterInfoSession)11 NodeAddress (net.dempsy.transport.NodeAddress)11 Map (java.util.Map)10 Set (java.util.Set)10 Collectors (java.util.stream.Collectors)9 Assert.assertNotNull (org.junit.Assert.assertNotNull)9 Before (org.junit.Before)9 Collections (java.util.Collections)8