2011-12-19 11:07:59 +01:00
|
|
|
/**
|
2012-01-19 18:21:06 +01:00
|
|
|
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
|
2011-12-19 11:07:59 +01:00
|
|
|
*/
|
2012-05-22 11:37:09 +02:00
|
|
|
package docs.dispatcher;
|
2011-12-13 16:18:51 +01:00
|
|
|
|
|
|
|
|
//#imports
|
2012-05-07 20:37:56 +02:00
|
|
|
import akka.actor.*;
|
2011-12-13 16:18:51 +01:00
|
|
|
//#imports
|
|
|
|
|
|
|
|
|
|
//#imports-prio
|
|
|
|
|
import akka.event.Logging;
|
|
|
|
|
import akka.event.LoggingAdapter;
|
|
|
|
|
|
|
|
|
|
//#imports-prio
|
|
|
|
|
|
2011-12-21 20:34:46 +01:00
|
|
|
//#imports-prio-mailbox
|
|
|
|
|
import akka.dispatch.PriorityGenerator;
|
|
|
|
|
import akka.dispatch.UnboundedPriorityMailbox;
|
|
|
|
|
import com.typesafe.config.Config;
|
|
|
|
|
|
|
|
|
|
//#imports-prio-mailbox
|
|
|
|
|
|
2012-06-19 14:52:02 +02:00
|
|
|
//#imports-custom
|
|
|
|
|
import akka.dispatch.Envelope;
|
|
|
|
|
import akka.dispatch.MessageQueue;
|
|
|
|
|
import akka.dispatch.MailboxType;
|
|
|
|
|
import java.util.Queue;
|
|
|
|
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
|
|
|
|
|
|
|
|
//#imports-custom
|
|
|
|
|
|
2011-12-13 16:18:51 +01:00
|
|
|
import org.junit.After;
|
|
|
|
|
import org.junit.Before;
|
|
|
|
|
import org.junit.Test;
|
|
|
|
|
import scala.Option;
|
2012-10-15 21:34:31 +02:00
|
|
|
import scala.concurrent.ExecutionContext;
|
2011-12-13 16:18:51 +01:00
|
|
|
|
|
|
|
|
import com.typesafe.config.ConfigFactory;
|
|
|
|
|
|
2012-05-22 11:37:09 +02:00
|
|
|
import docs.actor.MyUntypedActor;
|
2011-12-13 16:18:51 +01:00
|
|
|
import akka.testkit.AkkaSpec;
|
|
|
|
|
|
|
|
|
|
public class DispatcherDocTestBase {
|
|
|
|
|
|
|
|
|
|
ActorSystem system;
|
|
|
|
|
|
|
|
|
|
@Before
|
|
|
|
|
public void setUp() {
|
|
|
|
|
system = ActorSystem.create("MySystem",
|
2012-09-26 10:56:25 +02:00
|
|
|
ConfigFactory.parseString(
|
|
|
|
|
DispatcherDocSpec.config()).withFallback(AkkaSpec.testConf()));
|
2011-12-13 16:18:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@After
|
|
|
|
|
public void tearDown() {
|
2011-12-14 16:32:25 +01:00
|
|
|
system.shutdown();
|
2011-12-13 16:18:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void defineDispatcher() {
|
|
|
|
|
//#defining-dispatcher
|
2012-02-24 14:28:17 +01:00
|
|
|
ActorRef myActor =
|
|
|
|
|
system.actorOf(new Props(MyUntypedActor.class).withDispatcher("my-dispatcher"),
|
|
|
|
|
"myactor3");
|
2011-12-13 16:18:51 +01:00
|
|
|
//#defining-dispatcher
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void definePinnedDispatcher() {
|
|
|
|
|
//#defining-pinned-dispatcher
|
2011-12-27 13:35:50 +01:00
|
|
|
ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class)
|
2012-02-24 14:28:17 +01:00
|
|
|
.withDispatcher("my-pinned-dispatcher"));
|
2011-12-13 16:18:51 +01:00
|
|
|
//#defining-pinned-dispatcher
|
|
|
|
|
}
|
2012-10-15 21:34:31 +02:00
|
|
|
|
|
|
|
|
public void compileLookup() {
|
|
|
|
|
//#lookup
|
|
|
|
|
// this is scala.concurrent.ExecutionContext
|
|
|
|
|
// for use with Futures, Scheduler, etc.
|
|
|
|
|
final ExecutionContext ex = system.dispatchers().lookup("my-dispatcher");
|
|
|
|
|
//#lookup
|
|
|
|
|
}
|
2011-12-13 16:18:51 +01:00
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void priorityDispatcher() throws Exception {
|
|
|
|
|
//#prio-dispatcher
|
|
|
|
|
|
2012-09-26 10:56:25 +02:00
|
|
|
// We create a new Actor that just prints out what it processes
|
2012-02-24 14:28:17 +01:00
|
|
|
ActorRef myActor = system.actorOf(
|
2011-12-13 16:18:51 +01:00
|
|
|
new Props().withCreator(new UntypedActorFactory() {
|
|
|
|
|
public UntypedActor create() {
|
|
|
|
|
return new UntypedActor() {
|
2012-02-24 14:28:17 +01:00
|
|
|
LoggingAdapter log =
|
|
|
|
|
Logging.getLogger(getContext().system(), this);
|
2011-12-13 16:18:51 +01:00
|
|
|
{
|
2012-09-19 23:55:53 +02:00
|
|
|
getSelf().tell("lowpriority", getSelf());
|
|
|
|
|
getSelf().tell("lowpriority", getSelf());
|
|
|
|
|
getSelf().tell("highpriority", getSelf());
|
|
|
|
|
getSelf().tell("pigdog", getSelf());
|
|
|
|
|
getSelf().tell("pigdog2", getSelf());
|
|
|
|
|
getSelf().tell("pigdog3", getSelf());
|
|
|
|
|
getSelf().tell("highpriority", getSelf());
|
|
|
|
|
getSelf().tell(PoisonPill.getInstance(), getSelf());
|
2011-12-13 16:18:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void onReceive(Object message) {
|
|
|
|
|
log.info(message.toString());
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
2012-02-24 14:28:17 +01:00
|
|
|
}).withDispatcher("prio-dispatcher"));
|
2011-12-13 16:18:51 +01:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Logs:
|
|
|
|
|
'highpriority
|
|
|
|
|
'highpriority
|
|
|
|
|
'pigdog
|
|
|
|
|
'pigdog2
|
|
|
|
|
'pigdog3
|
|
|
|
|
'lowpriority
|
|
|
|
|
'lowpriority
|
|
|
|
|
*/
|
|
|
|
|
//#prio-dispatcher
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 10; i++) {
|
|
|
|
|
if (myActor.isTerminated())
|
|
|
|
|
break;
|
|
|
|
|
Thread.sleep(100);
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-12-21 20:34:46 +01:00
|
|
|
|
2012-09-26 10:56:25 +02:00
|
|
|
static
|
2011-12-21 20:34:46 +01:00
|
|
|
//#prio-mailbox
|
2012-09-26 10:56:25 +02:00
|
|
|
public class MyPrioMailbox extends UnboundedPriorityMailbox {
|
|
|
|
|
// needed for reflective instantiation
|
|
|
|
|
public MyPrioMailbox(ActorSystem.Settings settings, Config config) {
|
2012-02-24 14:28:17 +01:00
|
|
|
// Create a new PriorityGenerator, lower prio means more important
|
|
|
|
|
super(new PriorityGenerator() {
|
2012-02-21 18:24:38 +01:00
|
|
|
@Override
|
|
|
|
|
public int gen(Object message) {
|
|
|
|
|
if (message.equals("highpriority"))
|
|
|
|
|
return 0; // 'highpriority messages should be treated first if possible
|
|
|
|
|
else if (message.equals("lowpriority"))
|
2012-02-24 14:28:17 +01:00
|
|
|
return 2; // 'lowpriority messages should be treated last if possible
|
2012-05-07 20:37:56 +02:00
|
|
|
else if (message.equals(PoisonPill.getInstance()))
|
2012-02-24 14:28:17 +01:00
|
|
|
return 3; // PoisonPill when no other left
|
2012-02-21 18:24:38 +01:00
|
|
|
else
|
2012-02-24 14:28:17 +01:00
|
|
|
return 1; // By default they go between high and low prio
|
2012-02-21 18:24:38 +01:00
|
|
|
}
|
|
|
|
|
});
|
2011-12-21 20:34:46 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//#prio-mailbox
|
2012-09-26 10:56:25 +02:00
|
|
|
|
|
|
|
|
static
|
2012-06-19 14:52:02 +02:00
|
|
|
//#mailbox-implementation-example
|
2012-09-26 10:56:25 +02:00
|
|
|
public class MyUnboundedMailbox implements MailboxType {
|
2012-06-19 14:52:02 +02:00
|
|
|
|
|
|
|
|
// This constructor signature must exist, it will be called by Akka
|
|
|
|
|
public MyUnboundedMailbox(ActorSystem.Settings settings, Config config) {
|
|
|
|
|
// put your initialization code here
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The create method is called to create the MessageQueue
|
|
|
|
|
public MessageQueue create(Option<ActorRef> owner, Option<ActorSystem> system) {
|
|
|
|
|
return new MessageQueue() {
|
|
|
|
|
private final Queue<Envelope> queue = new ConcurrentLinkedQueue<Envelope>();
|
|
|
|
|
|
|
|
|
|
// these must be implemented; queue used as example
|
2012-09-26 10:56:25 +02:00
|
|
|
public void enqueue(ActorRef receiver, Envelope handle) {
|
|
|
|
|
queue.offer(handle);
|
|
|
|
|
}
|
2012-06-19 14:52:02 +02:00
|
|
|
public Envelope dequeue() { return queue.poll(); }
|
|
|
|
|
public int numberOfMessages() { return queue.size(); }
|
|
|
|
|
public boolean hasMessages() { return !queue.isEmpty(); }
|
|
|
|
|
public void cleanUp(ActorRef owner, MessageQueue deadLetters) {
|
|
|
|
|
for (Envelope handle: queue) {
|
|
|
|
|
deadLetters.enqueue(owner, handle);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//#mailbox-implementation-example
|
2011-12-13 16:18:51 +01:00
|
|
|
}
|