summaryrefslogblamecommitdiff
path: root/test/files/jvm/actmig-loop-react.scala
blob: c9a36645264c8f6ef37180bb54b374209b78489e (plain) (tree)
1
2
3
4



                                                                                                   




































                                                                 
                                                        









                                      
      



































                                               
                                                        

















                                            
      








                                                    
                                                    



















                                                           
      






                                              
                                                        








                                                                
      





                        
                                         





























                                                                                            
/**
 * NOTE: Code snippets from this test are included in the Actor Migration Guide. In case you change
 * code in these tests prior to the 2.10.0 release please send the notification to @vjovanov.
 */
import scala.actors.Actor._
import scala.actors._
import scala.actors.migration._
import java.util.concurrent.{ TimeUnit, CountDownLatch }
import scala.collection.mutable.ArrayBuffer
import scala.concurrent.duration._
import scala.concurrent.{ Promise, Await }

object Test {
  val finishedLWCR, finishedTNR, finishedEH = Promise[Boolean]
  val finishedLWCR1, finishedTNR1, finishedEH1 = Promise[Boolean]

  def testLoopWithConditionReact() = {
    // Snippet showing composition of receives
    // Loop with Condition Snippet - before
    val myActor = actor {
      var c = true
      loopWhile(c) {
        react {
          case x: Int =>
            // do task
            println("do task")
            if (x == 42) {
              c = false
              finishedLWCR1.success(true)
            }
        }
      }
    }

    myActor.start()
    myActor ! 1
    myActor ! 42

    Await.ready(finishedLWCR1.future, 5 seconds)

    // Loop with Condition Snippet - migrated
    val myAkkaActor = ActorDSL.actor(new StashingActor {

      def receive = {
        case x: Int =>
          // do task
          println("do task")
          if (x == 42) {
            finishedLWCR.success(true)
            context.stop(self)
          }
      }
    })
    myAkkaActor ! 1
    myAkkaActor ! 42
  }

  def testNestedReact() = {
    // Snippet showing composition of receives
    // Loop with Condition Snippet - before
    val myActor = actor {
      var c = true
      loopWhile(c) {
        react {
          case x: Int =>
            // do task
            println("do task " + x)
            if (x == 42) {
              c = false
            } else {
              react {
                case y: String =>
                  println("do string " + y)
              }
            }
            println("after react")
            finishedTNR1.success(true)
        }
      }
    }
    myActor.start()

    myActor ! 1
    myActor ! "I am a String"
    myActor ! 42

    Await.ready(finishedTNR1.future, 5 seconds)

    // Loop with Condition Snippet - migrated
    val myAkkaActor = ActorDSL.actor(new StashingActor {

      def receive = {
        case x: Int =>
          // do task
          println("do task " + x)
          if (x == 42) {
            println("after react")
            finishedTNR.success(true)
            context.stop(self)
          } else
            context.become(({
              case y: String =>
                println("do string " + y)
            }: Receive).andThen(x => {
              unstashAll()
              context.unbecome()
            }).orElse { case x => stash() })
      }
    })

    myAkkaActor ! 1
    myAkkaActor ! "I am a String"
    myAkkaActor ! 42

  }

  def exceptionHandling() = {
    // Stashing actor with act and exception handler
    val myActor = ActorDSL.actor(new StashingActor {

      def receive = { case _ => println("Dummy method.") }
      override def act() = {
        loop {
          react {
            case "fail" =>
              throw new Exception("failed")
            case "work" =>
              println("working")
            case "die" =>
              finishedEH1.success(true)
              exit()
          }
        }
      }

      override def exceptionHandler = {
        case x: Exception => println("scala got exception")
      }

    })

    myActor ! "work"
    myActor ! "fail"
    myActor ! "die"

    Await.ready(finishedEH1.future, 5 seconds)
    // Stashing actor in Akka style
    val myAkkaActor = ActorDSL.actor(new StashingActor {
      def receive = PFCatch({
        case "fail" =>
          throw new Exception("failed")
        case "work" =>
          println("working")
        case "die" =>
          finishedEH.success(true)
          context.stop(self)
      }, { case x: Exception => println("akka got exception") })
    })

    myAkkaActor ! "work"
    myAkkaActor ! "fail"
    myAkkaActor ! "die"
  }

  def main(args: Array[String]): Unit = {
    testLoopWithConditionReact()
    Await.ready(finishedLWCR.future, 5 seconds)
    exceptionHandling()
    Await.ready(finishedEH.future, 5 seconds)
    testNestedReact()
    Await.ready(finishedTNR.future, 5 seconds)
  }

}

// As per Jim Mcbeath's blog (http://jim-mcbeath.blogspot.com/2008/07/actor-exceptions.html)
class PFCatch(f: PartialFunction[Any, Unit],
  handler: PartialFunction[Exception, Unit])
  extends PartialFunction[Any, Unit] {

  def apply(x: Any) = {
    try {
      f(x)
    } catch {
      case e: Exception if handler.isDefinedAt(e) => handler(e)
    }
  }

  def isDefinedAt(x: Any) = f.isDefinedAt(x)
}

object PFCatch {
  def apply(f: PartialFunction[Any, Unit],
    handler: PartialFunction[Exception, Unit]) = new PFCatch(f, handler)
}