Search in sources :

Example 1 with KeyedMessageWithType

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

the class MessageProcessMessageHandlingTest method testMpMessageTypeInfoOnReturn.

@Test
public void testMpMessageTypeInfoOnReturn() throws Exception {
    final MessageProcessor<TestMpWithReturn> helper = new MessageProcessor<TestMpWithReturn>(new TestMpWithReturn());
    helper.validate();
    final Message m = new Message("yo");
    final TestMpWithReturn instance = helper.newInstance();
    final List<KeyedMessageWithType> kms = helper.invoke(instance, km(m));
    assertEquals(1, kms.size());
    assertNotNull(kms.get(0).messageTypes);
    assertEquals(5, kms.get(0).messageTypes.length);
}
Also used : KeyedMessageWithType(net.dempsy.messages.KeyedMessageWithType) Message(net.dempsy.lifecycle.annotations.TestMps.Message) MessageProcessor(net.dempsy.lifecycle.annotation.MessageProcessor) TestMpWithReturn(net.dempsy.lifecycle.annotations.TestMps.TestMpWithReturn) Test(org.junit.Test)

Example 2 with KeyedMessageWithType

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

the class LockingContainer method outputPass.

// This method MUST NOT THROW
@Override
protected void outputPass() {
    if (!prototype.isOutputSupported())
        return;
    // take a snapshot of the current container state.
    final LinkedList<InstanceWrapper> toOutput = new LinkedList<InstanceWrapper>(instances.values());
    Executor executorService = null;
    Semaphore taskLock = null;
    executorService = super.getOutputExecutorService();
    if (executorService != null)
        taskLock = new Semaphore(outputConcurrency);
    // This keeps track of the number of concurrently running
    // output tasks so that this method can wait until they're
    // all done to return.
    // 
    // It's also used as a condition variable signaling on its
    // own state changes.
    final AtomicLong numExecutingOutputs = new AtomicLong(0);
    // keep going until all of the outputs have been invoked
    while (toOutput.size() > 0 && isRunning.get()) {
        for (final Iterator<InstanceWrapper> iter = toOutput.iterator(); iter.hasNext(); ) {
            final InstanceWrapper wrapper = iter.next();
            boolean gotLock = false;
            gotLock = wrapper.tryLock();
            if (gotLock) {
                // so don't do anything else with this.
                if (wrapper.isEvicted()) {
                    iter.remove();
                    wrapper.releaseLock();
                    continue;
                }
                // only called while holding the lock
                final Object instance = wrapper.getInstance();
                final Semaphore taskSepaphore = taskLock;
                // This task will release the wrapper's lock.
                final Runnable task = new Runnable() {

                    @Override
                    public void run() {
                        final List<KeyedMessageWithType> response;
                        try {
                            if (isRunning.get() && !wrapper.isEvicted())
                                response = invokeOperation(instance, Operation.output, null);
                            else
                                response = null;
                        } finally {
                            wrapper.releaseLock();
                            // this signals that we're done.
                            synchronized (numExecutingOutputs) {
                                numExecutingOutputs.decrementAndGet();
                                numExecutingOutputs.notifyAll();
                            }
                            if (taskSepaphore != null)
                                taskSepaphore.release();
                        }
                        if (response != null) {
                            try {
                                dispatcher.dispatch(response);
                            } catch (final Exception de) {
                                if (isRunning.get())
                                    LOGGER.warn("Failed on subsequent dispatch of " + response + ": " + de.getLocalizedMessage());
                            }
                        }
                    }
                };
                synchronized (numExecutingOutputs) {
                    numExecutingOutputs.incrementAndGet();
                }
                if (executorService != null) {
                    try {
                        taskSepaphore.acquire();
                        executorService.execute(task);
                    } catch (final RejectedExecutionException e) {
                        // this may happen because of a race condition between the
                        taskSepaphore.release();
                        // we never got into the run so we need to release the lock
                        wrapper.releaseLock();
                    } catch (final InterruptedException e) {
                        // this can happen while blocked in the semaphore.acquire.
                        // if we're no longer running we should just get out
                        // of here.
                        // 
                        // Not releasing the taskSepaphore assumes the acquire never executed.
                        // if (since) the acquire never executed we also need to release the
                        // wrapper lock or that Mp will never be usable again.
                        // we never got into the run so we need to release the lock
                        wrapper.releaseLock();
                    }
                } else
                    task.run();
                iter.remove();
            }
        // end if we got the lock
        }
    // end loop over every Mp
    }
    // now make sure all of the running tasks have completed
    synchronized (numExecutingOutputs) {
        while (numExecutingOutputs.get() > 0) {
            try {
                numExecutingOutputs.wait();
            } catch (final InterruptedException e) {
                // waiting for all of the threads to finish
                if (!isRunning.get())
                    break;
            // otherwise continue checking.
            }
        }
    }
// =======================================================
}
Also used : Semaphore(java.util.concurrent.Semaphore) LinkedList(java.util.LinkedList) ContainerException(net.dempsy.container.ContainerException) DempsyException(net.dempsy.DempsyException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) Executor(java.util.concurrent.Executor) KeyedMessageWithType(net.dempsy.messages.KeyedMessageWithType)

Example 3 with KeyedMessageWithType

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

the class TestManagedRoutingStrategy method testInboundWithOutbound.

@Test
public void testInboundWithOutbound() throws Exception {
    final int numShardsToExpect = Integer.parseInt(Utils.DEFAULT_TOTAL_SHARDS);
    final Manager<RoutingStrategy.Inbound> manager = new Manager<>(RoutingStrategy.Inbound.class);
    try (final RoutingStrategy.Inbound ib = manager.getAssociatedInstance(ManagedInbound.class.getPackage().getName())) {
        final ClusterId cid = setTestName("testInboundWithOutbound");
        final ContainerAddress oca = new ContainerAddress(new DummyNodeAddress("here"), 0);
        final Infrastructure infra = makeInfra(session, sched);
        final Utils<ContainerAddress> msutils = new Utils<>(infra, cid.clusterName, oca);
        ib.setContainerDetails(cid, oca, (l, m) -> {
        });
        ib.start(infra);
        checkForShardDistribution(session, msutils, numShardsToExpect, 1);
        try (final ClusterInfoSession ses2 = sessFact.createSession();
            final RoutingStrategyManager obman = chain(new RoutingStrategyManager(), o -> o.start(makeInfra(ses2, sched)));
            final RoutingStrategy.Factory obf = obman.getAssociatedInstance(ManagedInbound.class.getPackage().getName())) {
            obf.start(makeInfra(ses2, sched));
            assertTrue(poll(o -> obf.isReady()));
            final RoutingStrategy.Router ob = obf.getStrategy(cid);
            assertTrue(poll(o -> obf.isReady()));
            final KeyedMessageWithType km = new KeyedMessageWithType(new Object(), new Object(), "");
            assertTrue(poll(o -> ob.selectDestinationForMessage(km) != null));
            final ContainerAddress ca = ob.selectDestinationForMessage(km);
            assertNotNull(ca);
            assertEquals("here", ((DummyNodeAddress) ca.node).name);
            // now disrupt the session
            session.close();
            try (ClusterInfoSession ses3 = sessFact.createSession();
                RoutingStrategy.Inbound ib2 = manager.getAssociatedInstance(ManagedInbound.class.getPackage().getName())) {
                ib2.setContainerDetails(cid, ca, (l, m) -> {
                });
                ib2.start(makeInfra(ses3, sched));
                assertTrue(poll(o -> ob.selectDestinationForMessage(km) != null));
            }
        }
    }
}
Also used : ShardAssignment(net.dempsy.router.shardutils.Utils.ShardAssignment) Arrays(java.util.Arrays) ClusterInfoException(net.dempsy.cluster.ClusterInfoException) ClusterInfoSession(net.dempsy.cluster.ClusterInfoSession) ContainerAddress(net.dempsy.router.RoutingStrategy.ContainerAddress) KeyedMessageWithType(net.dempsy.messages.KeyedMessageWithType) NodeAddress(net.dempsy.transport.NodeAddress) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) Utils(net.dempsy.router.shardutils.Utils) Supplier(java.util.function.Supplier) RoutingStrategyManager(net.dempsy.router.RoutingStrategyManager) HashSet(java.util.HashSet) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RoutingStrategy(net.dempsy.router.RoutingStrategy) Map(java.util.Map) Manager(net.dempsy.Manager) TestInfrastructure(net.dempsy.util.TestInfrastructure) ClusterId(net.dempsy.config.ClusterId) Logger(org.slf4j.Logger) Assert.assertNotNull(org.junit.Assert.assertNotNull) ClusterInfoSessionFactory(net.dempsy.cluster.ClusterInfoSessionFactory) Assert.assertTrue(org.junit.Assert.assertTrue) Set(java.util.Set) Test(org.junit.Test) Collectors(java.util.stream.Collectors) Consumer(java.util.function.Consumer) List(java.util.List) ConditionPoll.poll(net.dempsy.utils.test.ConditionPoll.poll) Infrastructure(net.dempsy.Infrastructure) Functional.chain(net.dempsy.util.Functional.chain) BaseRouterTestWithSession(net.dempsy.router.BaseRouterTestWithSession) Assert.assertEquals(org.junit.Assert.assertEquals) RoutingStrategyManager(net.dempsy.router.RoutingStrategyManager) ClusterId(net.dempsy.config.ClusterId) RoutingStrategyManager(net.dempsy.router.RoutingStrategyManager) Manager(net.dempsy.Manager) ContainerAddress(net.dempsy.router.RoutingStrategy.ContainerAddress) KeyedMessageWithType(net.dempsy.messages.KeyedMessageWithType) Utils(net.dempsy.router.shardutils.Utils) RoutingStrategy(net.dempsy.router.RoutingStrategy) TestInfrastructure(net.dempsy.util.TestInfrastructure) Infrastructure(net.dempsy.Infrastructure) ClusterInfoSession(net.dempsy.cluster.ClusterInfoSession) Test(org.junit.Test)

Example 4 with KeyedMessageWithType

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

the class TestInstanceManager method testMultipleInstanceCreation.

@Test
public void testMultipleInstanceCreation() throws Exception {
    final CombinedMP prototype = new CombinedMP();
    try (final LockingContainer manager = setupContainer(new MessageProcessor<CombinedMP>(prototype))) {
        final DummyDispatcher dispatcher = ((DummyDispatcher) manager.getDispatcher());
        assertEquals("starts with no instances", 0, manager.getProcessorCount());
        final KeyedMessageWithType message1 = km(new MessageOne(123));
        final InstanceWrapper wrapper1 = manager.getInstanceForKey(message1.key);
        manager.dispatch(message1, true);
        final CombinedMP instance1 = (CombinedMP) wrapper1.getInstance();
        final KeyedMessageWithType message2 = km(new MessageOne(456));
        final InstanceWrapper wrapper2 = manager.getInstanceForKey(message2.key);
        manager.dispatch(message2, false);
        final CombinedMP instance2 = (CombinedMP) wrapper2.getInstance();
        assertEquals("instances were created", 2, manager.getProcessorCount());
        assertEquals(new ReturnString("MessageOne"), dispatcher.lastDispatched.message);
        assertEquals("message count to instance1", 1, instance1.messages.size());
        assertEquals("message count to instance2", 1, instance2.messages.size());
        assertSame("message1 went to instance1", message1.message, instance1.messages.get(0));
        assertSame("message2 went to instance2", message2.message, instance2.messages.get(0));
        assertEquals(new ReturnString("MessageOne"), dispatcher.lastDispatched.message);
    }
}
Also used : InstanceWrapper(net.dempsy.container.locking.LockingContainer.InstanceWrapper) KeyedMessageWithType(net.dempsy.messages.KeyedMessageWithType) Test(org.junit.Test)

Example 5 with KeyedMessageWithType

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

the class TestInstanceManager method testOutputShortCircuitsIfNoOutputMethod.

@Test
public void testOutputShortCircuitsIfNoOutputMethod() throws Exception {
    final CombinedMP prototype = new CombinedMP();
    final Container manager = setupContainer(new MessageProcessor<CombinedMP>(prototype));
    final DummyDispatcher dispatcher = ((DummyDispatcher) manager.getDispatcher());
    // we need to dispatch messages to create MP instances
    final KeyedMessageWithType message1 = km(new MessageOne(1));
    final KeyedMessageWithType message2 = km(new MessageOne(2));
    manager.dispatch(message1, true);
    manager.dispatch(message2, false);
    assertEquals(new ReturnString("MessageOne"), dispatcher.lastDispatched.message);
    manager.invokeOutput();
    // output messages are NOT considered "processed" if there is no output method on the MP.
    assertEquals("number of processed messages should include outputs.", 2, ((ClusterMetricGetters) statsCollector).getProcessedMessageCount());
}
Also used : Container(net.dempsy.container.Container) KeyedMessageWithType(net.dempsy.messages.KeyedMessageWithType) Test(org.junit.Test)

Aggregations

KeyedMessageWithType (net.dempsy.messages.KeyedMessageWithType)24 Test (org.junit.Test)19 InstanceWrapper (net.dempsy.container.locking.LockingContainer.InstanceWrapper)7 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)4 DempsyException (net.dempsy.DempsyException)4 Container (net.dempsy.container.Container)4 LinkedList (java.util.LinkedList)3 Infrastructure (net.dempsy.Infrastructure)3 Manager (net.dempsy.Manager)3 ClusterInfoException (net.dempsy.cluster.ClusterInfoException)3 ClusterInfoSession (net.dempsy.cluster.ClusterInfoSession)3 ClusterId (net.dempsy.config.ClusterId)3 ContainerException (net.dempsy.container.ContainerException)3 RoutingStrategy (net.dempsy.router.RoutingStrategy)3 ContainerAddress (net.dempsy.router.RoutingStrategy.ContainerAddress)3 RoutingStrategyManager (net.dempsy.router.RoutingStrategyManager)3 NodeAddress (net.dempsy.transport.NodeAddress)3 Functional.chain (net.dempsy.util.Functional.chain)3 TestInfrastructure (net.dempsy.util.TestInfrastructure)3 ConditionPoll.poll (net.dempsy.utils.test.ConditionPoll.poll)3