All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scavenger.backend.ReactiveContext.scala Maven / Gradle / Ivy

The newest version!
package scavenger.backend

import akka.actor.ActorRef
import akka.pattern.ask
import akka.util.Timeout
import scala.collection.mutable.HashMap
import scala.concurrent._
import scala.concurrent.duration._
import scala.language.postfixOps
import scavenger._
import scavenger.categories.formalccc
import scavenger.backend.Cache.DumpKeys

/** Implementation of a context that interfaces with
  * the reactive ActorSystem-model.
  *
  * It translates method calls into messages and sends them
  * to an actor on the same node (Worker or Master).
  *
  * Classes of this type provide a bridge between the `Actor`
  * world and the `Future` world, similarly to the `PromiseActorRef`,
  * used in the ask-pattern.
  *
  * This context translates method calls into messages by 
  * sending mutable (!) promises to the actor. 
  * To ensure that the mutable promise does to spread across the
  * actor system, a `DemilitarizedZone` component awaits the 
  * messages on the other side.
  *
  * Such a context can be used by a `Computation` that is
  * being executed on a node, or by a user who submits jobs
  * to the `Master` node.
  *
  * @since 2.1
  * @author Andrey Tyukin
  */
class ReactiveContext(
  private val actorRef: ActorRef,
  implicit val executionContext: ExecutionContext
) extends Context {

  def submit[X](job: Computation[X]): Future[X] = {
    // That's kind of like Hawking's "grey holes":
    // Promises are thrown into the "black hole", Futures escape...
    val p = Promise[Any]
    actorRef ! DemilitarizedZone.Compute(job, p)
    p.future.map{ 
      a => a.asInstanceOf[X] 
    }
  }

  def asExplicitComputation[X](job: Computation[X]): 
    Future[ExplicitComputation[X]] = {
    val p = Promise[ExplicitComputation[Any]]
    actorRef ! DemilitarizedZone.GetExplicitComputation(job, p)
    p.future.map{ 
      a => a.asInstanceOf[ExplicitComputation[X]] 
    }
  }

  /** Asks the underlying actor to dump content of it's cache.
    *
    * Intended to be used for testing purposes.
    */
  private[scavenger] def dumpCacheKeys: List[formalccc.Elem] = {
    implicit val to = Timeout(60 seconds)
    Await.result(
      (actorRef ? DumpKeys).mapTo[List[formalccc.Elem]],
      60 seconds
    )
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy