Skip to content

Instantly share code, notes, and snippets.

@KirinDave
Created February 20, 2011 17:58
Show Gist options
  • Save KirinDave/836153 to your computer and use it in GitHub Desktop.
Save KirinDave/836153 to your computer and use it in GitHub Desktop.
An actor to address a tight-timeline horde problem, where many request for identical (and potentially non-trivial) pieces of data enter the system at once.
package com.swipr.lib
import akka.actor._
import akka.dispatch._
import scala.collection.immutable._
package HordeProtocol {
case class GetOrCreate(key: Any, valueGenerator: () => Any)
case class ClearJob(keyToClear: Any, value: Any)
}
class HordeMaster extends Actor {
import HordeProtocol._
type Generator = () => Any
private var currentJobs = Map[Any,List[CompletableFuture[Any]]]()
override def receive = {
case GetOrCreate(key,vg) => getOrGenerateJob(self.senderFuture.get,
key,
vg.asInstanceOf[Generator])
case ClearJob(key,vg) => clearJob(key, vg)
}
private def getOrGenerateJob(sender: CompletableFuture[Any],
key: Any,
g: Generator) = {
if(currentJobs.contains(key)) {
val pendingActors = sender +: currentJobs(key)
currentJobs = currentJobs + (key -> pendingActors)
} else {
val endpoint = self
currentJobs += (key -> List(sender))
Actor.spawn { endpoint ! ClearJob(key,g()) }
}
}
private def clearJob(key: Any, result: Any) = {
currentJobs.getOrElse(key,List()) foreach { (a) =>
a.completeWithResult(result)
}
currentJobs = currentJobs - key
}
}
object HordeMaster {
import HordeProtocol._
def computeWithKey[R](key: String)(thunk: => R)(implicit i: ActorRef): Option[R] = {
val generator: () => R = () => thunk
val m = GetOrCreate(key,generator)
(i !! m).asInstanceOf[Option[R]]
}
}
@KirinDave
Copy link
Author

If anyone who happens to peek at this code has advice for how to restructure computeWithKey and where I should put an implicit (and how I should keep other ActorRefs from falling in there), I'm very open to ideas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment