Scala Actors: if react never returns, why does it need to be in a loop{}, and why doesn't while(true) work? - scala

Just getting started on Scala Actors. The Scala website says:
Thread-blocking operations can be avoided by using react to wait for
new messages (the event-based pendant of receive). However, there is a
(usually small) price to pay: react never returns.
...
Note that using react inside a while loop does not work! However,
since loops are common there is special library support for it in form
of a loop function. It can be used like this:
loop {
react {
case A => ...
case B => ...
}
}
I'm now confused - there seems to be a contradiction:
a) If react never returns, then what's the point of putting it in a loop?
b) Since loop repeatedly executes a block, how is it any different to while(true) - why doesn't while work, and in what way does it "not work"?

Both functions, loop and react are not pure. loop takes a call by name parameter and react a PartialFunction, both set variables on the raw actor. This is because an actor does not have a thread attached all the time. It will become active only when there is a message in it's messagebox. This is why a while(true) will lead to 100% cpu usage and the actor not responding.

I found an explanation that answers part a) of my question, in one of Haller and Odersky's papers on Actors (my emphasis below):
The central idea is as follows: An actor that waits in a receive
statement is not represented by a blocked thread but by a closure that
captures the rest of the actor's computation. The closure is executed
once a message is sent to the actor that matches one of the message
patterns specied in the receive. The execution of the closure is
\piggy-backed" on the thread of the sender.
If the receiving closure
terminates, control is returned to the sender as if a procedure
returns. If the receiving closure blocks in a second receive, control
is returned to the sender by throwing a special exception that unwinds
the receiver's call stack.
A necessary condition for the scheme to
work is that receivers never return normally to their enclosing actor.
In other words, no code in an actor can depend on the termination or
the result of a receive block...

Related

Is sending futures in Akka messages OK?

I'm working on implementing a small language to send tasks to execution and control execution flow. After the sending a task to my system, the user gets a future (on which it can call a blocking get() or flatMap() ). My question is: is it OK to send futures in Akka messages?
Example: actor A sends a message Response to actor B and Response contains a future among its fields. Then at some point A will fulfill the promise from which the future was created. After receiving the Response, B can call flatMap() or get() at any time.
I'm asking because Akka messages should be immutable and work even if actors are on different JVMs. I don't see how my example above can work if actors A and B are on different JVMs. Also, are there any problems with my example even if actors are on same JVM?
Something similar is done in the accepted answer in this stackoverflow question. Will this work if actors are on different JVMs?
Without remoting it's possible, but still not advisable. With remoting in play it won't work at all.
If your goal is to have an API that returns Futures, but uses actors as the plumbing underneath, one approach could be that the API creates its own actor internally that it asks, and then returns the future from that ask to the caller. The actor spawned by the API call is guaranteed to be local to the API instance and can communicate with the rest of the actor system via the regular tell/receive mechanism, so that there are no Futures sent as messages.
class MyTaskAPI(actorFactory: ActorRefFactory) {
def doSomething(...): Future[SomethingResult] = {
val taskActor = actorFactory.actorOf(Props[MyTaskActor])
taskActor ? DoSomething(...).mapTo[SomethingResult]
}
}
where MyTaskActor receives the DoSomething, captures the sender, sends out the request for task processince and likely becomes a receiving state for SomethingResult which finally responds to the captured sender and stops itself. This approach creates two actors per request, one explicitly, the MyTaskActor and one implicitly, the handler of the ask, but keeps all state inside of actors.
Alternately, you could use the ActorDSL to create just one actor inline of doSomething and use a captured Promise for completion instead of using ask:
class MyTaskAPI(system: System) {
def doSomething(...): Future[SomethingResult] = {
val p = Promise[SomethingResult]()
val tmpActor = actor(new Act {
become {
case msg:SomethingResult =>
p.success(msg)
self.stop()
}
}
system.actorSelection("user/TaskHandler").tell(DoSomething(...), tmpActor)
p.future
}
}
This approach is a bit off the top of my head and it does use a shared value between the API and the temp actor, which some might consider a smell, but should give an idea how to implement your workflow.
If you're asking if it's possible, then yes, it's possible. Remote actors are basically interprocess communication. If you set everything up on both machines to a state where both can properly handle the future, then it should be good. You don't give any working example so I can't really delve deeper into it.

Using future callback inside akka actor

I've found in Akka docs:
When using future callbacks, such as onComplete, onSuccess, and onFailure, inside actors you need to carefully avoid closing over the containing actor’s reference, i.e. do not call methods or access mutable state on the enclosing actor from within the callback.
So does it mean that i should always use future pipeTo self and then call some functions? Or i can still use callbacks with method, then how should i avoid concurrency bugs?
It means this:
class NotThreadSafeActor extends Actor {
import context.dispatcher
var counter = 0
def receive = {
case any =>
counter = counter + 1
Future {
// do something else on a future
Thread.sleep(2000)
}.onComplete {
_ => counter = counter + 1
}
}
}
In this example, both the actor's receive method, and the Future's onComplete change the mutable variable counter. In this toy example its easier to see, but the Future call might be nested methods that equally capture a mutable variable.
The issue is that the onComplete call might execute on a different thread to the actor itself, so its perfectly possible to have one thread executing receive and another executing onComplete thus giving you a race condition. Which negates the point of an actor in the first place.
Yes, you should send a message to the enclosing actor if the callback mutates internal state of the actor. This is the easiest (and preferred) way to avoid races.
I think I would be remiss if I did not mention here that I've made a small utility for circumventing this limitation. In other words, my answer to your question is No, you shouldn't use such an inconvenient workaround, you should use https://github.com/makoConstruct/RequestResponseActor
how does it work?
Basically, behind the futures and the promises, it transmits every query in a Request(id:Int, content:Any), and when it receives Response(id, result) it completes the future that corresponds to id with the value of result. It's also capable of transmitting failures, and as far as I can tell, akka can only register query timeouts. The RequestResponseActor supplies a special implicit execution context to apply to callbacks attached to the futures waiting for a Response message. This blunt execution context ensures they're executed while the Response message is being processed, thus ensuring the Actor has exclusive access to its state when the future's callbacks fire.
Maybe this can help. It is an experiment I did and the test is quite conclusive... however, it is still an experiment, so do not take that as an expertise.
https://github.com/Adeynack/ScalaLearning/tree/master/ActorThreadingTest/src/main/scala/david/ActorThreadingTest
Open to comments or suggestions, of course.
Futures with actors is a subject I am very interested in.

actor:possible to send and receive nested in a receive

When process a message, is it possible to send out an message to another actor and wait for that actor to reply, and consume the replied message and then continue, like the following, is it doable?
val lineMap=HashMap[String,Int]()
receive {
case bigTaskMap=>
for (line <-readSomeFile){
if(lineMap.get(line)==None){
anotherActor!line // that actor will reply a hashmap which contain the key for line
receive {
case x:HashMap => lineMap=x
}
}
lineMap.get(line) // use that value to do further work
}
}
This answer is for Akka (old Scala actors are deprecated in Scala 2.10).
Yes. You can use ask to get a future (rather than creating a fully-fledged actor yourself) and then call onComplete on the Future returned to set an action which will be executed when the Future's value (or an error) becomes available. Don't worry about how quickly the Future might yield a value - it doesn't matter, because the onComplete action will be executed even if the Future is already available when onComplete is called!
However, be very careful: you should not directly access any of the state (i.e. the variables) in the containing actor in your action(s), because the onComplete action(s) will not run in the same execution context as the actor (i.e. they could be running at the same time as the original actor is processing a message). Instead, send further messages back to the original actor, or forward them on.
In fact, in some cases you may find the simplest thing to do is simply to send a message, and let the original actor handle the reply. become and unbecome may help here. However, again, be careful if using become, that in the actor's new behaviour, it doesn't drop "ordinary" messages that should be handled in the ordinary way.

Easiest way to do idle processing in a Scala Actor?

I have a scala actor that does some work whenever a client requests it. When, and only when no client is active, I would like the Actor to do some background processing.
What is the easiest way to do this? I can think of two approaches:
Spawn a new thread that times out and wakes up the actor periodically. A straight forward approach, but I would like to avoid creating another thread (to avoid the extra code, complexity and overhead).
The Actor class has a reactWithin method, which could be used to time out from the actor itself. But the documentation says the method doesn't return. So, I am not sure how to use it.
Edit; a clarification:
Assume that the background task can be broken down into smaller units that can be independently processed.
Ok, I see I need to put my 2 cents. From the author's answer I guess the "priority receive" technique is exactly what is needed here. It is possible to find discussion in "Erlang: priority receive question here at SO". The idea is to accept high priority messages first and to accept other messages only in absence of high-priority ones.
As Scala actors are very similar to Erlang, a trivial code to implement this would look like this:
def act = loop {
reactWithin(0) {
case msg: HighPriorityMessage => // process msg
case TIMEOUT =>
react {
case msg: HighPriorityMessage => // process msg
case msg: LowPriorityMessage => // process msg
}
}
}
This works as follows. An actor has a mailbox (queue) with messages. The receive (or receiveWithin) argument is a partial function and Actor library looks for a message in a mailbox which can be applied to this partial function. In our case it would be an object of HighPriorityMessage only. So, if Actor library finds such a message, it applies our partial function and we are processing a message of high priority. Otherwise, reactWithin with timeout 0 calls our partial function with argument TIMEOUT and we immediately try to process any possible message from the queue (as it waits for a message we cannot exclude a possiblity to get HighPriorityMessage).
It sounds like the problem you describe is not well suited to the actor sub-system. An Actor is designed to sequentially process its message queue:
What should happen if the actor is performing the background work and a new task arrives?
An actor can only find out about this is it is continuously checking its mailbox as it performs the background task. How would you implement this (i.e. how would you code the background tasks as a unit of work so that the actor could keep interrupting and checking the mailbox)?
What should happen if the actor has many background tasks in its mailbox in front of the main task?
Do these background tasks get thrown away, or sent to another actor? If the latter, how can you prevent CPU time being given to that actor to perform the tasks?
All in all, it sounds much more like you need to explore some grid-style software that can run in the background (like Data Synapse)!
Just after asking this question I tried out some completely whacky code and it seems to work fine. I am not sure though if there is a gotcha in it.
import scala.actors._
object Idling
object Processor extends Actor {
start
import Actor._
def act() = {
loop {
// here lie dragons >>>>>
if (mailboxSize == 0) this ! Idling
// <<<<<<
react {
case msg:NormalMsg => {
// do the normal work
reply(answer)
}
case Idling=> {
// do the idle work in chunks
}
case msg => println("Rcvd unknown message:" + msg)
}
}
}
}
Explanation
Any code inside the argument of loop but before the call to react seems to get called when the Actor is about to wait for a message. I am sending a Idling message to self here. In the handler for this message I ensure that the mailbox-size is 0, before doing the processing.

How to create non-blocking methods in Scala?

What is a good way of creating non-blocking methods in Scala? One way I can think of is to create a thread/actor and the method just send a message to the thread and returns. Is there a better way of creating a non-blocking method?
Use scala.actors.Future:
import actors._
def asyncify[A, B](f: A => B): A => Future[B] = (a => Futures.future(f(a)))
// normally blocks when called
def sleepFor(seconds: Int) = {
Thread.sleep(seconds * 1000)
seconds
}
val asyncSleepFor = asyncify(sleepFor)
val future = asyncSleepFor(5) // now it does NOT block
println("waiting...") // prints "waiting..." rightaway
println("future returns %d".format(future())) // prints "future returns 5" after 5 seconds
Overloaded "asyncify" that takes a function with more than one parameter is left as an exercise.
One caveat, however, is exception handling. The function that is being "asyncified" has to handle all exceptions itself by catching them. Behavior for exceptions thrown out of the function is undefined.
Learn about actors.
It depends on your definition of "blocking." Strictly speaking, anything that requires acquisition of a lock is blocking. All operations that are dependent on an actor's internal state acquire a lock on the actor. This includes message sends. If lots of threads try to send a message to an actor all-at-once they have to get in line.
So if you really need non-blocking, there are various options in java.util.concurrent.
That being said, from a practical perspective actors give you something that close enough to non-blocking because none of the synchronized operations do a significant amount of work, so chances are actors meet your need.