Protected
Protected
Routing / Patterns (Scala)

Akka-core includes some building blocks to build more complex message flow handlers, they are listed and explained below:


Dispatcher


A Dispatcher is an actor that routes incoming messages to outbound actors.

To use it you can either create a Dispatcher through the dispatcherActor() factory method


import se.scalablesolutions.akka.actor.Actor._
import se.scalablesolutions.akka.patterns.Patterns._
 
//Our message types
case object Ping
case object Pong
 
//Two actors, one named Pinger and one named Ponger
//The actor(pf) method creates an anonymous actor and starts it
val pinger = actor { case x => println("Pinger: " + x) }
val ponger = actor { case x => println("Ponger: " + x) }
 
//A dispatcher that dispatches Ping messages to the pinger
//and Pong messages to the ponger
val d = dispatcherActor {
  case Ping => pinger
  case Pong => ponger
}
 
d ! Ping //Prints "Pinger: Ping"
d ! Pong //Prints "Ponger: Pong"


Or by mixing in se.scalablesolutions.akka.patterns.Dispatcher:

import se.scalablesolutions.akka.actor.Actor
import se.scalablesolutions.akka.actor.Actor._
import se.scalablesolutions.akka.patterns.Dispatcher
 
//Our message types
case object Ping
case object Pong
 
class MyDispatcher extends Actor with Dispatcher {
//Our pinger and ponger actors
  val pinger = actor { case x => println("Pinger: " + x) }
  val ponger = actor { case x => println("Ponger: " + x) }
//When we get a ping, we dispatch to the pinger
//When we get a pong, we dispatch to the ponger
  def routes = {
    case Ping => pinger
    case Pong => ponger
  }
}
 
//Create an instance of our dispatcher, and start it
val d = actorOf[MyDispatcher].start
 
d ! Ping //Prints "Pinger: Ping"
d ! Pong //Prints "Ponger: Pong"
 


LoadBalancer


A LoadBalancer is an actor that forwards messages it receives to a boundless sequence of destination actors.

Example using the loadBalancerActor() factory method:
import se.scalablesolutions.akka.actor.Actor._
import se.scalablesolutions.akka.patterns.Patterns._
import se.scalablesolutions.akka.patterns.CyclicIterator
 
//Our message types
case object Ping
case object Pong
 
//Two actors, one named Pinger and one named Ponger
//The actor(pf) method creates an anonymous actor and starts it
 
val pinger = actor { case x => println("Pinger: " + x) }
val ponger = actor { case x => println("Ponger: " + x) }
 
//A load balancer that given a sequence of actors dispatches them accordingly
//a CyclicIterator works in a round-robin-fashion
 
val d = loadBalancerActor( new CyclicIterator( List(pinger,ponger) ) )
 
d ! Pong //Prints "Pinger: Pong"
d ! Pong //Prints "Ponger: Pong"
d ! Ping //Prints "Pinger: Ping"
d ! Ping //Prints "Ponger: Ping"

Or by mixing in se.scalablesolutions.akka.patterns.LoadBalancer

import se.scalablesolutions.akka.actor._
import se.scalablesolutions.akka.actor.Actor._
import se.scalablesolutions.akka.patterns.{ LoadBalancer, CyclicIterator }
 
//Our message types
case object Ping
case object Pong
 
//A load balancer that balances between a pinger and a ponger
class MyLoadBalancer extends Actor with LoadBalancer {
  val pinger = actor { case x => println("Pinger: " + x) }
  val ponger = actor { case x => println("Ponger: " + x) }
 
  val seq = new CyclicIterator[ActorRef](List(pinger,ponger))
}
 
//Create an instance of our loadbalancer, and start it
val d = actorOf[MyLoadBalancer].start
 
d ! Pong //Prints "Pinger: Pong"
d ! Pong //Prints "Ponger: Pong"
d ! Ping //Prints "Pinger: Ping"
d ! Ping //Prints "Ponger: Ping"

Also, instead of using the CyclicIterator, you can create your own message distribution algorithms, there’s already one that dispatches depending on target mailbox size, effectively dispatching to the one that’s got fewest messages to process right now.

Example http://pastie.org/984889
Home
close
Loading...
Home Turn Off "Getting Started"
close
Loading...