Method call inside Actor freezes in Scala - scala

I have the following code. If I comment the call to "foo()" inside the actor's body, the code works fine. But if "foo()" is activated... my code freezes!
Anyone kwnows why?
import scala.actors.Actor._
object Main extends Application{
def foo() = {
println("I'm on foo")
}
def testActor() = {
val target = self
for(i <- 1 to 100){
actor{
foo()
target ! i
}
}
var total = 0
receive{
case x:Int => total += x
}
total
}
println("Result: " + testActor())
}

"testActor" is called while the "Main" class is initializing. The actor code is executing in a different thread(not the main thread) and it's blocked and can not send any message because it's trying to access a method in a class (Main in this case) that is being initialized in the main thread. "receive" hangs because it can not receive any message.
Do not use "extends Application". Use "def main(args: Array[String])" and save yourself a lot of trouble.
See http://scala-blogs.org/2008/07/application-trait-considered-harmful.html

The Application trait and its use is at fault here. When you have code running within the body of a Application rather than within a main method, that code is actually running as part of the constructor. So at the point where you call the testActor() method, the object hasn't actually finished initialising.
To fix it, move the println line into a main method:
def main (args: Array[String]) {
println("Result: " + testActor())
}
Because this problem happens so easily, the Application trait is considered to be bad news.

Related

Failing a scalatest when akka actor throws exception outside of the test thread

I've had a situation come up and bite me a few times where I'm testing an Actor and the Actor throws an exception unexpectedly (due to a bug), but the test still passes. Now most of the time the exception in the Actor means that whatever the test is verifying won't come out properly so it the test fails, but in rare cases that's not true. The exception occurs in a different thread than the test runner so the test runner knows nothing about it.
One example is when I'm using a mock to verify some dependency gets called, and due to a mistake in the Actor code I call an unexpected method in the mock. That causes the mock to throw an exception which blows up the actor but not the test. Sometimes this can even cause downstream tests to fail mysteriously because of how the Actor blew up. For example:
// using scala 2.10, akka 2.1.1, scalatest 1.9.1, easymock 3.1
// (FunSpec and TestKit)
class SomeAPI {
def foo(x: String) = println(x)
def bar(y: String) = println(y)
}
class SomeActor(someApi: SomeAPI) extends Actor {
def receive = {
case x:String =>
someApi.foo(x)
someApi.bar(x)
}
}
describe("problem example") {
it("calls foo only when it receives a message") {
val mockAPI = mock[SomeAPI]
val ref = TestActorRef(new SomeActor(mockAPI))
expecting {
mockAPI.foo("Hi").once()
}
whenExecuting(mockAPI) {
ref.tell("Hi", testActor)
}
}
it("ok actor") {
val ref = TestActorRef(new Actor {
def receive = {
case "Hi" => sender ! "Hello"
}
})
ref.tell("Hi", testActor)
expectMsg("Hello")
}
}
"problemExample" passes, but then downstream "ok actor" fails for some reason I don't really understand... with this exception:
cannot reserve actor name '$$b': already terminated
java.lang.IllegalStateException: cannot reserve actor name '$$b': already terminated
at akka.actor.dungeon.ChildrenContainer$TerminatedChildrenContainer$.reserve(ChildrenContainer.scala:86)
at akka.actor.dungeon.Children$class.reserveChild(Children.scala:78)
at akka.actor.ActorCell.reserveChild(ActorCell.scala:306)
at akka.testkit.TestActorRef.<init>(TestActorRef.scala:29)
So, I can see ways of catching this sort of thing by examining the logger output in afterEach handlers. Definitely doable, although a little complicated in cases where I actually expect an exception and that's what I'm trying to test. But is there any more direct way of handling this and making the test fail?
Addendum: I have looked at the TestEventListener and suspect there's maybe something there that would help, but I can't see it. The only documentation I could find was about using it to check for expected exceptions, not unexpected ones.
Thinking in Actors there is also another solution: failures travel to the supervisor, so that is the perfect place to catch them and feed them into the test procedure:
val failures = TestProbe()
val props = ... // description for the actor under test
val failureParent = system.actorOf(Props(new Actor {
val child = context.actorOf(props, "child")
override val supervisorStrategy = OneForOneStrategy() {
case f => failures.ref ! f; Stop // or whichever directive is appropriate
}
def receive = {
case msg => child forward msg
}
}))
You can send to the actor under test by sending to failureParent and all failures—expected or not—go to the failures probe for inspection.
Other than examining the logs, I can think of two ways to fail tests when an actor crashes:
Ensure that no Terminated message is received
Check the TestActorRef.isTerminated property
The latter option is deprecated, so I'll ignore it.
Watching Other Actors from Probes describes how to setup a TestProbe. In this case it might look something like:
val probe = TestProbe()
probe watch ref
// Actual test goes here ...
probe.expectNoMessage()
If the actor dies due to an exception it will generate the Terminated message. If that happens during the test and you expect something else, the test will fail. If it happens after your last message expectation, then the expectNoMessage() should fail when Terminated is received.
Okay, I've had a little time to play with this. I've got a nice solution that uses an event listener and filter to catch errors. (Checking isTerminated or using TestProbes is probably good in more focused cases but seems awkward when trying to make something to mix into any old test.)
import akka.actor.{Props, Actor, ActorSystem}
import akka.event.Logging.Error
import akka.testkit._
import com.typesafe.config.Config
import org.scalatest._
import org.scalatest.matchers.ShouldMatchers
import org.scalatest.mock.EasyMockSugar
import scala.collection.mutable
trait AkkaErrorChecking extends ShouldMatchers {
val system:ActorSystem
val errors:mutable.MutableList[Error] = new mutable.MutableList[Error]
val errorCaptureFilter = EventFilter.custom {
case e: Error =>
errors += e
false // don't actually filter out this event - it's nice to see the full output in console.
}
lazy val testListener = system.actorOf(Props(new akka.testkit.TestEventListener {
addFilter(errorCaptureFilter)
}))
def withErrorChecking[T](block: => T) = {
try {
system.eventStream.subscribe(testListener, classOf[Error])
filterEvents(errorCaptureFilter)(block)(system)
withClue(errors.mkString("Akka error(s):\n", "\n", ""))(errors should be('empty))
} finally {
system.eventStream.unsubscribe(testListener)
errors.clear()
}
}
}
You can just use withErrorChecking inline at specific spots, or mix it into a Suite and use withFixture to do it globally across all tests, like this:
trait AkkaErrorCheckingSuite extends AkkaErrorChecking with FunSpec {
override protected def withFixture(test: NoArgTest) {
withErrorChecking(test())
}
}
If you use this in my original example, then you will get the first test "calls foo only when it receives a message" to fail, which is nice because that's where the real failure is. But the downstream test will still fail as well due to the system blowing up. To fix that, I went a step further and used a fixture.Suite to instance a separate TestKit for each test. That solves lots of other potential test isolation issues when you have noisy actors. It requires a little more ceremony declaring each test but I think it's well worth it. Using this trait with my original example I get the first test failing and the second one passing which is just what I want!
trait IsolatedTestKit extends ShouldMatchers { this: fixture.Suite =>
type FixtureParam = TestKit
// override this if you want to pass a Config to the actor system instead of using default reference configuration
val actorSystemConfig: Option[Config] = None
private val systemNameRegex = "[^a-zA-Z0-9]".r
override protected def withFixture(test: OneArgTest) {
val fixtureSystem = actorSystemConfig.map(config => ActorSystem(systemNameRegex.replaceAllIn(test.name, "-"), config))
.getOrElse (ActorSystem (systemNameRegex.replaceAllIn(test.name, "-")))
try {
val errorCheck = new AkkaErrorChecking {
val system = fixtureSystem
}
errorCheck.withErrorChecking {
test(new TestKit(fixtureSystem))
}
}
finally {
fixtureSystem.shutdown()
}
}
}

How can we override the react construct of scala actors?

The usual way of detecting the type of message received in scala actors is by
loop{
react{
case x: String =>
}
}
However, I want to know how can we override this implementation of react construct so that we can do implicit logging of the message that is received.
I am trying to implement a use case mentioned below ->
1. Before a message is matched to any case class, I want to write a log statement on console / file showing the occurance of the message.
2. We can log these messages explicitly by println() / log4j logging . However, I want to design a generic logger for scala actors which will log all the messages sent or received.
Any help in this regard will be helpful.
Thanks in advance
First, be aware that the Scala actors library is being deprecated in favor of Akka. So this answer won't be helpful very long (though the other actors library will continue to be available for a while--and since it's open source potentially forever if people want to maintain it).
Anyway, the react method is defined in scala.actors.Actor. Simply fail to import it, or hide it with your own. Your own what?
Well, the method just takes a PartialFunction[Any,Unit]. So, your should also:
def react(pf: PartialFunction[Any,Unit]): Nothing = { /*how?;*/ Actor.react(/*what?*/) }
You really only have access to the partial function, and you have to defer to Actor.react to do what you want. So you need to wrap pf in another PartialFunction that performs your logging. So you can
val qf = new PartialFunction[Any,Unit] {
def isDefinedAt(a: Any) = pf.isDefinedAt(a)
def apply(a: Any): Unit = {
log(a) // Maybe add more logic to know what a is
pf(a)
}
}
If you want to see messages that come in and get examined but are not actually consumed, you could do more with isDefinedAt also.
So, obviously enough, I hope, /*how?*/ is the above to define (create) qf, and /*what?*/ is just qf.
If you want to know whether a is a case class, the answer is that you cannot (by design). A case class is just syntactic sugar on top of ordinary Scala features; it's just there to save you typing. See, for instance, this question.
However, you can get pretty close by pattern matching for Product and checking whether it has a copy method:
case class M(i: Int)
val a: Any = M(5)
scala> a match {
case p: Product if p.getClass.getMethods.exists(_.getName=="copy") => println("Yes")
case _ => println("No")
}
Yes
If you really want to get fancy, check if copy has the same number and type of parameters as the constructor.
//Following is a code for a logReact Method that does the same thing as react but also logs the message received hope this works for you
import scala.actors.Actor;
import scala.actors.Actor._
trait ActorLogging extends Actor {
def logReact(handler: PartialFunction[Any, Unit]): Nothing = {
val handler2: PartialFunction[Any, Unit] = {
case x =>
println("Inside Logs -- with message recieved -- " + x.toString);
handler.apply(x);
}
super.react(handler2)
}
}
class sumAct extends Actor with ActorLogging {
def act() {
loop {
logReact {
case a: Int =>
println("Inside actor Sum Act Received the message -- " + a)
exit;
}
}
}
}
object ActorLog {
def main(args: Array[String]): Unit = {
var s: sumAct = new sumAct;
s.start();
s ! 1.toInt;
}
}

Message passing using Actors

I am writing a program using Actors in scala in which an actor (Actor1) accepts two numbers as command line arguments and sends a message to another actor Actor2 (which calculates their sum). Actor2 sends the result to Actor1, who prints it on the screen.
class Actor1 extends Actor {
def main(args: Array[String]) {
val n= Integer.parseInt(args(0))
val k= Integer.parseInt(args(1))
val actor2 = new Actor2
actor2 ! (n, k)
}
def act()
{
react{
case num: Integer =>
println(num)
case _=>
println("Sum not received")
exit
}
}
}
class Actor2 extends Actor {
def act(){
loop
{
react
{
case(n:Int, k:Int) =>
val i = n + k
val actor1 = new Actor1
actor1 ! i}
}
}
}
Is it possible to define main() inside the class that extends Actor, and is there any other way to accept command line arguments by the Actor?
It shows the error: class Actor1 needs to be abstract, since method act in trait Reactor of type ()Unit is not defined.
First things first: You should consider using akka instead of the default Scala actors. It's just better.. in pretty much every aspect.
That aside, here are a few answers for your:
Your main method should be in a standalone object (not a companion object). So use something like this: object Main { def main(args:Array[String]) { ... } } and start your program via the Main object/class. (This is due to the definition inside the Actor1 class being non-static and the problem that if you define a companion object the .class filenames collide.)
In your code, something seems to have gone wrong with the brackets - or did you place Actor2 inside the Actor1 class on purpose? It's cleaner, if you just make three separate classes/objects: Actor1, Actor2, Main.
When you create Scala actors, you have to explicitly start them (not so with akka 2.x). So you miss your calls to actor1.start and such. Note that your program will then not terminate before your actors have terminated, so don't wonder if it doesn't stop anymore after you add that.
Finally, some minor hints:
You may want to consider using !? and send back your answer to the original caller, as this also allows you to have a proper termination condition.
Integer.parseInt("0") can be written more simply as "0".toInt

Akka actors, Futures, and closures

I read in the Akka docs that it's dangerous to close over variables from an enclosing actor.
Warning
In this case you need to carefully avoid closing over the
containing actor’s reference, i.e. do not call methods on the
enclosing actor from within the anonymous Actor class. This would
break the actor encapsulation and may introduce synchronization bugs
and race conditions because the other actor’s code will be scheduled
concurrently to the enclosing actor.
Now, I have two actors, one of which requests something from the second and does something with the result. In this example below I have put together, actor Accumulator retrieves numbers from actor NumberGenerator and adds them up, reporting the sum along the way.
This can be done in at least two different ways as this example shows with two different receive functions (A vs B). The difference between the two is that A does not close over the counter variable; instead it awaits an integer and sums it up, while B creates a Future that closes over counter and does the sum. This happens within an anonymous actor created just to process onSuccess, if I understand properly how this works.
import com.esotericsoftware.minlog.Log
import akka.actor.{Actor, Props}
import akka.pattern.{ask, pipe}
import akka.util.Timeout
import akka.util.duration._
case object Start
case object Request
object ActorTest {
var wake = 0
val accRef = Main.actorSystem.actorOf(Props[Accumulator], name = "accumulator")
val genRef = Main.actorSystem.actorOf(Props[NumberGenerator], name = "generator")
Log.info("ActorTest", "Starting !")
accRef ! Start
}
class Accumulator extends Actor {
var counter = 0
implicit val timeout = Timeout(5 seconds)
// A: WITHOUT CLOSURE
def receive = {
case Start => ask(ActorTest.genRef, Request).mapTo[Int] pipeTo self
case x: Int => counter += x; Log.info("Accumulator", "counter = " + counter); self ! Start
}
// B: WITH CLOSURE
def receive = {
case Start => ask(ActorTest.genRef, Request).mapTo[Int] onSuccess {
case x: Int => counter += x; Log.info("Accumulator", "counter = " + counter); self ! Start
}
}
}
class NumberGenerator extends Actor {
val rand = new java.util.Random()
def receive = {
case Request => sender ! rand.nextInt(11)-5
}
}
Is it absolutely evil to use closures in this case ? Of course I could use an AtomicInteger instead of an Int, or in some networking scenario using, say, netty, issue a write operation on a threadsafe channel, but this is not my point here.
To the risk of asking the ridiculous: is there a way for the Future's onSuccess to execute in this actor instead of an anonymous middle actor, without defining a case in the receive function ?
EDIT
To put it more clearly, my question is: Is there a way to force a series of Futures to run in the same thread as a given Actor ?
The problem is that the onSuccess is going to run in a different thread than the thread the actor's receive is going to run in. You could use the pipeTo approach, or use an Agent. Making counter an AtomicInteger would solve the problem, but it's not so clean - that is, it breaks the Actor model.
The easiest way of implementing such design is by using "fire-and-forget" semantic:
class Accumulator extends Actor {
private[this] var counter = 0
def receive = {
case Start => ActorTest.genRef ! Request
case x: Int => {
counter += x
Log.info("Accumulator", "counter = " + counter)
self ! Start
}
}
}
This solution is fully asynchronous, and you don't need any timeout.

Scala App val initialization in main method

I have some code:
object Main extends App
{
val NameTemplate = """^([A-Za-z]+)_(\d+)\.png""".r
override def main (args:Array[String])
{
// Why is NameTemplate null here?
}
}
Why is NameTemplate not initialized within the main method?
If you are using App trait, then you don't need to override main method - just write your code in the body of the object:
object Main extends App {
val NameTemplate = """^([A-Za-z]+)_(\d+)\.png""".r
println(NameTemplate)
val NameTemplate(name, version) = args(0)
println(name + " v" + version)
}
It works because App trait extends DelayedInit trait which has very special initialization procedure. You can even access arguments with args, as shown in the example.
You still need to write main method if you don't want to extend App, but in this case it will work as expected:
object Main {
val NameTemplate = """^([A-Za-z]+)_(\d+)\.png""".r
def main(args: Array[String]) {
println(NameTemplate)
val NameTemplate(name, version) = args(0)
println(name + " v" + version)
}
}
The DelayedInit trait (which App extends) causes rewriting of intialisation code to execute within a special delayedInit() method. This would then normally be invoked by main. Since you are overriding main, however, the delayedInit() code is never being invoked, and as such your value is not being initialised.
As #tenshi explains, you can get around this either by not extending App or by moving your main code into the body of your Main object.