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);
}
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.
}
}
}
// =======================================================
}
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));
}
}
}
}
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);
}
}
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());
}
Aggregations