diff --git a/akka-actor/src/main/scala/akka/dispatch/ExecutorBasedEventDrivenDispatcher.scala b/akka-actor/src/main/scala/akka/dispatch/ExecutorBasedEventDrivenDispatcher.scala index 019923b4b4..261a4c8170 100644 --- a/akka-actor/src/main/scala/akka/dispatch/ExecutorBasedEventDrivenDispatcher.scala +++ b/akka-actor/src/main/scala/akka/dispatch/ExecutorBasedEventDrivenDispatcher.scala @@ -236,14 +236,6 @@ object PriorityGenerator { def apply(priorityFunction: Any => Int): PriorityGenerator = new PriorityGenerator { def gen(message: Any): Int = priorityFunction(message) } - - /** - * Java API - * Creates a PriorityGenerator that uses the supplied function as priority generator - */ - def apply(priorityFunction: akka.japi.Function[Any, Int]): PriorityGenerator = new PriorityGenerator { - def gen(message: Any): Int = priorityFunction(message) - } } /** diff --git a/akka-actor/src/main/scala/akka/dispatch/MessageHandling.scala b/akka-actor/src/main/scala/akka/dispatch/MessageHandling.scala index d9129d422d..374b3b4b45 100644 --- a/akka-actor/src/main/scala/akka/dispatch/MessageHandling.scala +++ b/akka-actor/src/main/scala/akka/dispatch/MessageHandling.scala @@ -215,6 +215,9 @@ trait MessageDispatcher { * Trait to be used for hooking in new dispatchers into Dispatchers.fromConfig */ abstract class MessageDispatcherConfigurator { + /** + * Returns an instance of MessageDispatcher given a Configuration + */ def configure(config: Configuration): MessageDispatcher def mailboxType(config: Configuration): MailboxType = { diff --git a/akka-docs/pending/dispatchers-java.rst b/akka-docs/pending/dispatchers-java.rst index 5882f4d426..3aa1a34f13 100644 --- a/akka-docs/pending/dispatchers-java.rst +++ b/akka-docs/pending/dispatchers-java.rst @@ -47,6 +47,7 @@ There are six different types of message dispatchers: * Thread-based * Event-based +* Priority event-based * Work-stealing event-based * HawtDispatch-based event-driven @@ -127,6 +128,66 @@ If you don't define a the 'throughput' option in the configuration file then the Browse the `ScalaDoc `_ or look at the code for all the options available. +Priority event-based +^^^^^^^^^^^ + +Sometimes it's useful to be able to specify priority order of messages, that is done by using PriorityExecutorBasedEventDrivenDispatcher and supply +a java.util.Comparator[MessageInvocation] or use a akka.dispatch.PriorityGenerator (recommended): + +Creating a PriorityExecutorBasedEventDrivenDispatcher using PriorityGenerator in Java: + +.. code-block:: java + + package some.package; + + import akka.actor.*; + import akka.dispatch.*; + + public class Main { + // A simple Actor that just prints the messages it processes + public static class MyActor extends UntypedActor { + public void onReceive(Object message) throws Exception { + System.out.println(message); + } + } + + public static void main(String[] args) { + // Create a new PriorityGenerator, lower prio means more important + PriorityGenerator gen = new PriorityGenerator() { + public int gen(Object message) { + if (message == "highpriority") return 0; // "highpriority" messages should be treated first if possible + else if (message == "lowpriority") return 100; // "lowpriority" messages should be treated last if possible + else return 50; // We default to 50 + } + }; + // We create an instance of the actor that will print out the messages it processes + ActorRef ref = Actors.actorOf(MyActor.class); + // We create a new Priority dispatcher and seed it with the priority generator + ref.setDispatcher(new PriorityExecutorBasedEventDrivenDispatcher("foo", gen)); + + ref.start(); // Start the actor + ref.getDispatcher().suspend(ref); // Suspening the actor so it doesn't start to treat the messages before we have enqueued all of them :-) + ref.sendOneWay("lowpriority"); + ref.sendOneWay("lowpriority"); + ref.sendOneWay("highpriority"); + ref.sendOneWay("pigdog"); + ref.sendOneWay("pigdog2"); + ref.sendOneWay("pigdog3"); + ref.sendOneWay("highpriority"); + ref.getDispatcher().resume(ref); // Resuming the actor so it will start treating its messages + } + } + +Prints: + +highpriority +highpriority +pigdog +pigdog2 +pigdog3 +lowpriority +lowpriority + Work-stealing event-based ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/akka-docs/pending/dispatchers-scala.rst b/akka-docs/pending/dispatchers-scala.rst index 76ca982c65..9b67b7b58e 100644 --- a/akka-docs/pending/dispatchers-scala.rst +++ b/akka-docs/pending/dispatchers-scala.rst @@ -45,6 +45,7 @@ There are six different types of message dispatchers: * Thread-based * Event-based +* Priority event-based * Work-stealing * HawtDispatch-based event-driven @@ -103,6 +104,65 @@ If you don't define a the 'throughput' option in the configuration file then the Browse the `ScalaDoc `_ or look at the code for all the options available. +Priority event-based +^^^^^^^^^^^ + +Sometimes it's useful to be able to specify priority order of messages, that is done by using PriorityExecutorBasedEventDrivenDispatcher and supply +a java.util.Comparator[MessageInvocation] or use a akka.dispatch.PriorityGenerator (recommended): + +Creating a PriorityExecutorBasedEventDrivenDispatcher using PriorityGenerator in Java: + +.. code-block:: scala + + import akka.dispatch._ + + import akka.actor._ + + val gen = PriorityGenerator { // Create a new PriorityGenerator, lower prio means more important + case 'highpriority => 0 // 'highpriority messages should be treated first if possible + case 'lowpriority => 100 // 'lowpriority messages should be treated last if possible + case otherwise => 50 // We default to 50 + } + + val a = Actor.actorOf( // We create a new Actor that just prints out what it processes + new Actor { + def receive = { + case x => println(x) + } + }) + + // We create a new Priority dispatcher and seed it with the priority generator + a.dispatcher = new PriorityExecutorBasedEventDrivenDispatcher("foo", gen) + a.start // Start the Actor + + a.dispatcher.suspend(a) // Suspening the actor so it doesn't start to treat the messages before we have enqueued all of them :-) + + a ! 'lowpriority + + a ! 'lowpriority + + a ! 'highpriority + + a ! 'pigdog + + a ! 'pigdog2 + + a ! 'pigdog3 + + a ! 'highpriority + + a.dispatcher.resume(a) // Resuming the actor so it will start treating its messages + +Prints: + +'highpriority +'highpriority +'pigdog +'pigdog2 +'pigdog3 +'lowpriority +'lowpriority + Work-stealing event-based ^^^^^^^^^^^^^^^^^^^^^^^^^