bitcoin-atm

bitcoin atm for pyc inc.

git clone https://9o.is/git/bitcoin-atm.git

Minion.scala

(2565B)


      1 package inc.pyc.chimera
      2 package minions
      3 
      4 import akka.actor._
      5 import SupervisorStrategy._
      6 import akka.util.Timeout
      7 import concurrent.duration._
      8 
      9 /**
     10  * Minion does all the workload for Overlord. In case disaster 
     11  * occurs, the minion dies.
     12  */
     13 trait Minion {
     14   this: Actor with ActorLogging =>
     15     
     16     import context.dispatcher
     17   
     18     // Those damn minions better hurry
     19     implicit val timeout = Timeout(7 seconds)
     20     
     21     /**
     22      * Tasks that can be done by the minion.
     23      */
     24     val tasks: Receive
     25 
     26     /**
     27      * Minion kills itself
     28      */
     29     def die = context stop self
     30     
     31     /**
     32      * Minion runs its task and kills itself afterwards.
     33      */
     34     def runTask (func: => Unit) {
     35       func
     36       die
     37     }
     38     
     39     /**
     40      * Minion runs its task and kills itself after timer ends or
     41      * something else kills it.
     42      */
     43     def runTask_Wait (duration: FiniteDuration) (func: => Unit) {
     44       func
     45       context.system.scheduler.scheduleOnce(duration)(die)
     46     }
     47     
     48     /** 
     49      * Only Overlord creates and runs minions. 
     50      */
     51     def overlord = context parent
     52     
     53     
     54     def receive: Receive = tasks orElse {
     55       case term: Terminated => 
     56         log error "Minion could not complete its task"
     57         context stop self
     58     }
     59 }
     60 
     61 /**
     62  * Minion that launches a worker that can do the
     63  * job.
     64  */
     65 trait MinionWorker {
     66   this: Actor with Minion =>
     67     
     68     /** 
     69      * Props for worker actor 
     70      */
     71     def props: Props
     72   
     73     /**
     74      * Name for worker actor
     75      */
     76     def name: String
     77     
     78     /**
     79      * Creates a worker and kills it after it's 
     80      * done doing its job.
     81      */
     82     def workout (func: ActorRef => Unit) {
     83       val worker = context.actorOf(props, name)
     84       context watch worker
     85       func(worker)
     86       kill(worker)
     87     }
     88     
     89     /**
     90      * Creates a worker and kills it after it's 
     91      * done doing its job. Returns a result.
     92      */
     93     def workout_[T] (func: ActorRef => T): T = {
     94       val worker = context.actorOf(props, name)
     95       context watch worker
     96       val result = func(worker)
     97       kill(worker)
     98       result
     99     }
    100     
    101     /**
    102      * Kills the worker actor and becomes ready to die.
    103      * If the minion never hears from the worker, it kills itself.
    104      * @param worker worker actor
    105      */
    106     def kill(worker: ActorRef) = {
    107       context become dying(worker)
    108       worker ! PoisonPill
    109     }
    110   
    111     /**
    112      * Minion is dying. 
    113      * Once worker is dead, minion kills itself.
    114      */
    115     def dying(worker: ActorRef): Receive = {
    116       case Terminated(`worker`) => die
    117       case _ =>
    118     }
    119 }