package com.ibm.jactors.test; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import com.ibm.jactors.Actor; import com.ibm.jactors.DefaultMessage; import com.ibm.jactors.Message; /** * An actor that asks Consumer actors to produce items. * * @author BFEIGENB * */ public class ProducerActor extends TestableActor { @Override public void activate() { logger.trace("ProducerActor activate: %s", this); super.activate(); // logger.trace("expected: %s", expected); } @Override public void deactivate() { logger.trace("ProducerActor deactivate: %s", this); if (messages.size() > 0) { logger.trace("expected: %s", expected); DefaultActorTest.dumpMessages(messages); } super.deactivate(); } protected Map<String, Integer> expected = new ConcurrentHashMap<String, Integer>(); @Override protected void loopBody(Message m) { String subject = m.getSubject(); if ("produceN".equals(subject)) { Object[] input = (Object[]) m.getData(); int count = (Integer) input[0]; if (count > 0) { DefaultActorTest.sleeper(1); // this takes some time String type = (String) input[1]; // logger.trace("ProducerActor:%s produceN %d x %s; pending=%d", // getName(), count, type, messages.size()); logger.trace("ProducerActor:%s produceN %d x %s", getName(), count, type); // request the consumers to consume work (i.e., produce) Integer mcount = expected.get(type); if (mcount == null) { mcount = new Integer(0); } mcount += count; expected.put(type, mcount); DefaultMessage dm = new DefaultMessage("produce1", new Object[] { count, type }); getManager().send(dm, this, this); } } else if ("produce1".equals(subject)) { Object[] input = (Object[]) m.getData(); int count = (Integer) input[0]; if (count > 0) { sleep(100); // take a little time String type = (String) input[1]; // logger.trace("ProducerActor:%s produce1 %d x %s; pending=%d", // getName(), count, type, messages.size()); logger.trace("ProducerActor:%s produce1 %d x %s", getName(), count, type); m = new DefaultMessage("construct", type); getManager().send(m, this, getConsumerCategory()); m = new DefaultMessage("produce1", new Object[] { count - 1, type }); getManager().send(m, this, this); } } else if ("constructionComplete".equals(subject)) { String type = (String) m.getData(); // logger.trace("ProducerActor:%s constructionComplete %s; pending=%d", // getName(), type, messages.size()); logger.trace("ProducerActor:%s constructionComplete %s from %s", getName(), type, m.getSource() .getName()); Integer mcount = expected.get(type); if (mcount != null) { mcount--; expected.put(type, mcount); } } else if ("init".equals(subject)) { logger.trace("ProducerActor:%s init", getName()); // create some consumers // 1 to 3 x consumers per producer for (int i = 0; i < DefaultActorTest.nextInt(3) + 1; i++) { Actor a = getManager().createAndStartActor(ConsumerActor.class, String.format("%s_consumer%02d", getName(), i)); a.setCategory(getConsumerCategory()); if (actorTest != null) { actorTest.getTestActors().put(a.getName(), a); // logger.trace("created: %s", a); } } // request myself create some work items for (int i = 0; i < DefaultActorTest.nextInt(10) + 1; i++) { m = new DefaultMessage("produceN", new Object[] { DefaultActorTest.nextInt(10) + 1, DefaultActorTest.getItemTypes()[DefaultActorTest.nextInt(DefaultActorTest.getItemTypes().length)] }); getManager().send(m, this, this); } } else { logger.warning("ProducerActor:%s loopBody unknown subject: %s", getName(), subject); } } protected String getConsumerCategory() { return getName() + "_consumer"; } }