Scala actors - worst practices? [closed] - scala

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I feel a bit insecure about using actors in Scala. I have read documentation about how to do stuff, but I guess I would also need some DON'T rules in order to feel free to use them.
I think I am afraid that I will use them in a wrong way, and I will not even notice it.
Can you think of something, that, if applied, would result in breaking the benefits that Scala actors bring, or even erroneous results?

Avoid !? wherever possible. You will get a locked system!
Always send a message from an Actor-subsystem thread. If this means creating a transient Actor via the Actor.actor method then so be it:
case ButtonClicked(src) => Actor.actor { controller ! SaveTrade(trdFld.text) }
Add an "any other message" handler to your actor's reactions. Otherwise it is impossible to figure out if you are sending a message to the wrong actor:
case other => log.warning(this + " has received unexpected message " + other
Don't use Actor.actor for your primary actors, sublcass Actor instead. The reason for this is that it is only by subclassing that you can provide a sensible toString method. Again, debugging actors is very difficult if your logs are littered with statements like:
12:03 [INFO] Sending RequestTrades(2009-10-12) to scala.actors.Actor$anonfun$1
Document the actors in your system, explicitly stating what messages they will receive and precisely how they should calculate the response. Using actors results in the conversion of a standard procedure (normally encapsulated within a method) to become logic spread across multiple actor's reactions. It is easy to get lost without good documentation.
Always make sure you can communicate with your actor outside of its react loop to find its state. For example, I always declare a method to be invoked via an MBean which looks like the following code snippet. It can otherwise be very difficult to tell if your actor is running, has shut down, has a large queue of messages etc.
.
def reportState = {
val _this = this
synchronized {
val msg = "%s Received request to report state with %d items in mailbox".format(
_this, mailboxSize)
log.info(msg)
}
Actor.actor { _this ! ReportState }
}
Link your actors together and use trapExit = true - otherwise they can fail silently meaning your program is not doing what you think it is and will probably go out of memory as messages remain in the actor's mailbox.
I think that some other interesting choices around design-decisions to be made using actors have been highlighted here and here

I know this doesn't really answer the question, but you should at least take heart in the fact that message-based concurrency is much less prone to wierd errors than shared-memory-thread-based concurrency.
I presume you have seen the actor guidelines in Programming in Scala, but for the record:
Actors should not block while processing a message. Where you might want to block try to arrange to get a message later instead.
Use react {} rather than receive {} when possible.
Communicate with actors only via messages.
Prefer immutable messages.
Make messages self-contained.

Related

Aggregating multiple child actor responses in Akka Typed

I'm currently porting an Akka Classic app to Akka Typed. I have the following components:
HttpService - Not an Actor
JobDispatcher - An Actor
JobWorker - Child actor of JobDispatcher
The JobDispatcher is a singleton actor that orchestrates jobs. Each JobWorker is responsible for one "job" and knows the job's status.
The HTTP service will make an Ask to JobDispatcher, called GetJobStatuses.
The JobDispatcher will then Ask each of the JobWorkers what their status is, aggregate the results into a list, and reply to HttpService.
The way I did this in Akka Classic was to have JobDispatcher do all the Asks, put the Futures into a list of Futures, and then transform that into a Future of Lists, and when that aggregate Future completed, I would send the results to HttpService. It looked something like this:
val statusFutures: Seq[Future[JobStatus]] = jobWorkers map (jobWorker => (jobWorker ? GetJobStatus).mapTo[JobStatus])
val aggregateFuture: Future[Seq[SearchStatus]] = Future.sequence(statusFutures)
val theSender = context.sender()
aggregateFuture onComplete {
case Success(jobStatuses: Seq[JobStatus]) => {
theSender ! jobStatuses
}
case Failure(exception) => {
theSender ! exception
}
}
So, now that we're moving to Akka Typed, we're not supposed to use Futures / onComplete, but instead turn the Ask response into a message back ourself (JobDispatcher in this case). This is fairly straightforward for simple situations where I'm Asking one other actor for one reply. But in this case, I have a whole list of child actors from which I need to compile their responses.
The only thing I can think of is to make JobDispatcher hold a "state" of a list of JobWorker responses that I'm waiting for, track of which ones have been received, and when I've received them all, send a response message back to the HTTP service. This is further complicated by the fact that I may have multiple simultaneous Asks coming in from the HTTP service, and I'd have to track multiple copies of this "state", and somehow identify which HTTP request each one is for.
This is all WAY more complicated than the the aggregate Future solution above.
What is the simple/correct way to handle situations like this in Akka Typed?
The docs suggest using a per-session child actor for this situation. The child actor, being only associated with a single HTTP request is implicitly tracking exactly one copy of that state and is also able to manage the state of the process of scatter/gathering jobs (e.g. around timeouts and retries).
It's also worth noting that the example classic code has a massive bug: never call sender in code involving futures. Mixing futures and actors is superficially easy but also easy to turn into something that only works by coincidence (with tests often exhibiting that coincidental behavior).

Example of ask pattern in akka typed [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 3 years ago.
Improve this question
I am trying to figure out, how the ask pattern works. In the documentation, it says:
Perform a single request-response message interaction with another
actor, and transform the messages back to the protocol of this actor.
The interaction has a timeout (to avoid a resource leak). If the
timeout hits without any response it will be passed as a
Failure(java.util.concurrent.TimeoutException) to the mapResponse
function (this is the only "normal" way a Failure is passed to the
function).
For other messaging patterns with other actors, see
ActorContext#messageAdapter.
This method is thread-safe and can be called from other threads than
the ordinary actor message processing thread, such as
scala.concurrent.Future callbacks.
Could someone please provide an example to get a better understanding of ask pattern.
'Ask pattern' is used in the code outside of actors to communicate with actors. Akka will create an actor for you behind the scenes, send a message and wait for reply within timeout. None of this will block your thread because a Future result will be returned immediately which is expected to contain response later on. This is needed because actors can only communicate by sending messages and if you are not within an actor you can't receive a message. It's recommended to use 'tell' ! instead of 'ask' ? because it's more efficient but sometimes there is no choice so you have to bridge two worlds together with 'ask'.
Look for examples on internet or try to call actors from main method to get a feel of it.
When you need interact with another actor and also depend on its response you might use the tell method to send a message and wait for a new response message (fire-and-forget).
Due to the fact that Akka does not have guaranteed delivery, you might wait infinitely if the receiving actor is down.
Ask returns a Future[Response] that is either completed with a successful response or failed with a TimeoutException if there was no response within the specified timeout.
Please see the the example
The question you asked is related to akka typed and ask pattern API is slightly different to the standard (untyped) akka.
The examples can be found on akka docs and it is replicated here
trait CookieCommand {}
case class GiveMeCookies(replyTo: ActorRef[Cookies]) extends CookieCommand
case class Cookies(count: Int)
import akka.actor.typed.scaladsl.AskPattern._
// asking someone requires a timeout and a scheduler, if the timeout hits without response
// the ask is failed with a TimeoutException
implicit val timeout: Timeout = 3.seconds
implicit val scheduler = system.scheduler
val result: Future[Cookies] = cookieActorRef.ask(ref => GiveMeCookies(ref))
// the response callback will be executed on this execution context
implicit val ec = system.executionContext
result.onComplete {
case Success(cookies) => println("Yay, cookies!")
case Failure(ex) => println("Boo! didn't get cookies in time.")
}

Inconsistent behavior between local actor and remote actor

This is sort of a follow up to an earlier question at Scala variable binding when used with Actors
Against others' advice, I decided to make a message containing a closure and mutate the variable that closure is closed under between messages.. and explicitly wait for them.
The environment is akka 1.2 on scala 2.9
Consider the following
var minAge = 18
val isAdult = (age: Int) => age >= minAge
println((actor ? answer(19, isAdult)).get)
minAge = 20
println((actor ? answer(19, isAdult)).get)
The message handler for answer essentially applies isAdult to the first parameter (19).
When actor is local, I get the answers I expect.
true
false
But when it is remote, I get
false
false
I am simply curious why this would be the behavior? I would have expected consistent behavior between the two..
Thanks in advance!
Well, you have come across what may (or may not) be considered a problem for a system where the behaviour is specified by rules which are not enforced by the language. The same kind of thing happens in Java. Here:
Client: Data d = rmiServer.getSomeData();
Client: d.mutate()
Do you expect the mutation to happen on the server as well? A fundamental issue with any system which involves remote communication, especially when that communication is transparent to a client, is understanding where that communication is occurring and what, exactly, is going on.
The communication with the actor takes the form of message-passing
An effect can pass a boundary only by the mechanism of message-passing (that is, the effect must reside within the returned value)
The actor library may transparently handle the transmission of a message remotely
If your effect is not a message, it is not happening!
What you encounter here is what I would call “greediness” of Scala closures: they never close “by-value”, presumably because of the uniform access principle. This means that the closure contains an $outer reference which it uses to obtain the value of minAge. You did not give enough context to show what the $outer looks like in your test, hence I cannot be more precise in how it is serialized, from which would follow why it prints what you show.
One word, though: don’t send closures around like that, please. It is not a recipe for happiness, as you acknowledge yourself.

Scala actors: receive vs react

Let me first say that I have quite a lot of Java experience, but have only recently become interested in functional languages. Recently I've started looking at Scala, which seems like a very nice language.
However, I've been reading about Scala's Actor framework in Programming in Scala, and there's one thing I don't understand. In chapter 30.4 it says that using react instead of receive makes it possible to re-use threads, which is good for performance, since threads are expensive in the JVM.
Does this mean that, as long as I remember to call react instead of receive, I can start as many Actors as I like? Before discovering Scala, I've been playing with Erlang, and the author of Programming Erlang boasts about spawning over 200,000 processes without breaking a sweat. I'd hate to do that with Java threads. What kind of limits am I looking at in Scala as compared to Erlang (and Java)?
Also, how does this thread re-use work in Scala? Let's assume, for simplicity, that I have only one thread. Will all the actors that I start run sequentially in this thread, or will some sort of task-switching take place? For example, if I start two actors that ping-pong messages to each other, will I risk deadlock if they're started in the same thread?
According to Programming in Scala, writing actors to use react is more difficult than with receive. This sounds plausible, since react doesn't return. However, the book goes on to show how you can put a react inside a loop using Actor.loop. As a result, you get
loop {
react {
...
}
}
which, to me, seems pretty similar to
while (true) {
receive {
...
}
}
which is used earlier in the book. Still, the book says that "in practice, programs will need at least a few receive's". So what am I missing here? What can receive do that react cannot, besides return? And why do I care?
Finally, coming to the core of what I don't understand: the book keeps mentioning how using react makes it possible to discard the call stack to re-use the thread. How does that work? Why is it necessary to discard the call stack? And why can the call stack be discarded when a function terminates by throwing an exception (react), but not when it terminates by returning (receive)?
I have the impression that Programming in Scala has been glossing over some of the key issues here, which is a shame, because otherwise it's a truly excellent book.
First, each actor waiting on receive is occupying a thread. If it never receives anything, that thread will never do anything. An actor on react does not occupy any thread until it receives something. Once it receives something, a thread gets allocated to it, and it is initialized in it.
Now, the initialization part is important. A receiving thread is expected to return something, a reacting thread is not. So the previous stack state at the end of the last react can be, and is, wholly discarded. Not needing to either save or restore the stack state makes the thread faster to start.
There are various performance reasons why you might want one or other. As you know, having too many threads in Java is not a good idea. On the other hand, because you have to attach an actor to a thread before it can react, it is faster to receive a message than react to it. So if you have actors that receive many messages but do very little with it, the additional delay of react might make it too slow for your purposes.
The answer is "yes" - if your actors are not blocking on anything in your code and you are using react, then you can run your "concurrent" program within a single thread (try setting the system property actors.maxPoolSize to find out).
One of the more obvious reasons why it is necessary to discard the call stack is that otherwise the loop method would end in a StackOverflowError. As it is, the framework rather cleverly ends a react by throwing a SuspendActorException, which is caught by the looping code which then runs the react again via the andThen method.
Have a look at the mkBody method in Actor and then the seq method to see how the loop reschedules itself - terribly clever stuff!
Those statements of "discarding the stack" confused me also for a while and I think I get it now and this is my understanding now. In case of "receive" there is a dedicated thread blocking on the message (using object.wait() on a monitor) and this means that the complete thread stack is available and ready to continue from the point of "waiting" on receiving a message.
For example if you had the following code
def a = 10;
while (! done) {
receive {
case msg => println("MESSAGE RECEIVED: " + msg)
}
println("after receive and printing a " + a)
}
the thread would wait in the receive call until the message is received and then would continue on and print the "after receive and printing a 10" message and with the value of "10" which is in the stack frame before the thread blocked.
In case of react there is no such dedicated thread, the whole method body of the react method is captured as a closure and is executed by some arbitrary thread on the corresponding actor receiving a message. This means only those statements that can be captured as a closure alone will be executed and that's where the return type of "Nothing" comes to play. Consider the following code
def a = 10;
while (! done) {
react {
case msg => println("MESSAGE RECEIVED: " + msg)
}
println("after react and printing a " + a)
}
If react had a return type of void, it would mean that it is legal to have statements after the "react" call ( in the example the println statement that prints the message "after react and printing a 10"), but in reality that would never get executed as only the body of the "react" method is captured and sequenced for execution later (on the arrival of a message). Since the contract of react has the return type of "Nothing" there cannot be any statements following react, and there for there is no reason to maintain the stack. In the example above variable "a" would not have to be maintained as the statements after the react calls are not executed at all. Note that all the needed variables by the body of react is already be captured as a closure, so it can execute just fine.
The java actor framework Kilim actually does the stack maintenance by saving the stack which gets unrolled on the react getting a message.
Just to have it here:
Event-Based Programming without Inversion of Control
These papers are linked from the scala api for Actor and provide the theoretical framework for the actor implementation. This includes why react may never return.
I haven't done any major work with scala /akka, however i understand that there is a very significant difference in the way actors are scheduled.
Akka is just a smart threadpool which is time slicing execution of actors...
Every time slice will be one message execution to completion by an actor unlike in Erlang which could be per instruction?!
This leads me to think that react is better as it hints the current thread to consider other actors for scheduling where as receive "might" engage the current thread to continue executing other messages for the same actor.

Writing applications with Scala actors in practice II [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
Because my first question was so long, I'm asking this as a separate question. It's another one about the architecture of an actor-based application.
Keeping track of message paths through an Application
Let's take a piece of Java code:
public void deleteTrades(User user, Date date) {
PermissionSet ps = permissionService.findPermissions(user)
if (ps.hasPermission("delete")) {
Set<Trade> ts = peristence.findTrades(date);
reportService.sendCancelReports(ts);
positionService.updateWithDeletedTrades(ts);
}
}
In this code I have 4 separate components and the interaction between them required for the procedure deleteTrades is well-defined. It's completely contained in the method deleteTrades.
Modelling this with Actors and replacing my 4 components with 4 separate actors, how do I keep track (in my mind) of what a procedure involves? Particularly if I'm avoiding using the !? operator, then it's likely that I'll be sending a message ConditionalDelete to my PermissionActor, which will be sending a message GetTradesAndDelete to my PersistenceActor which will then send further messages etc etc. The code to process a delete will be strewn across my application.
It also means that pretty much every actor needs a handle on every other actor (in order to forward messages).
As in my previous question, how do people deal with this? Is there a good modelling tool which lets you keep track of all this? Do people use !? Am I turning too many components into Actors?
You use 5 components, definitely. There are actors dealing with specific tasks, and there's an orchestrator as well.
The question you must have, of course, is how do you chain this assynchronously. Well, it's actually somewhat easy, but it can obscure the code. Basically, you send each componenent the reply you want.
react {
case DeleteTrades(user,dates) =>
PermissionService ! FindPermissions(user, DeleteTradesPermissions(dates) _)
case DeleteTradesPermissions(dates)(ps) =>
if (ps hasPermission "delete")
Persistence ! FindTrades(date, DeleteTradesTradeSet _)
case DeleteTradesTradeSet(ts) =>
ReportService ! SendCancelReports(ts)
PositionService ! UpdateWithDeletedTrades(ts)
}
Here we use currying to pass "dates" in the first returning answer. If there's a lot of parameters associated with an interaction, it might be better to keep the information for all on-going transactions in a local HashSet, and just pass a token that you'll use to locate that information when receiving the answer.
Note that this single actor can handle multiple concurrent actions. In this particular case, just Delete transactions, but you could add any number of different actions for it to handle. When the data needed for one action is ready, then that action continues.
EDIT
Here's a working example of how these classes can be defined:
class Date
class User
class PermissionSet
abstract class Message
case class DeleteTradesPermission(date: Date)(ps: PermissionSet) extends Message
case class FindPermissions(u: User, r: (PermissionSet) => Message) extends Message
FindPermissions(new User, DeleteTradesPermission(new Date) _)
A few explanations on currying and functions. The class DeleteTradesPermission is curried so that you can pass a Date on it, and have some other function complete it with a PermissionSet. This would be the pattern of the answer messages.
Now, the class FindPermissions receives as a second parameter a function. The actor receiving this message will pass the return value to this function, and will receive a Message to be sent as answer. In this example, the message will have both the Date, which the calling actor sent, and PermissionSet, which the answering actor is providing.
If no answer is expected, such as the case of DeleteTrades, SendCancelReports and UpdateWithDeletedTrades for the purposes of this example, then you don't need to pass a function of the returning message.
Since we are expecting a function which returns a Message as parameter for those messages requiring an answer, we could define traits like this:
trait MessageResponse1[-T1] extends Function1[T1, Message]
trait MessageResponse2[-T1, -T2] extends Function2[T1, T2, Message]
...
Actors should not be used to replace traditional service components without considerations.
Most of the service components we write nowadays, by training, are stateless. Stateless service components are easier to manage (sans message class, etc) than actors. One of the things they lack though, when compare to actors, is asynchronous execution. But when clients are expecting the results to return synchronously most of the time, synchronous stateless service components are just fine for the job.
Actor is a good fit when there are internal states to manage. There is no need to do any synchronization inside "act()" to access internal states and to worry about race conditions. As long as "!?" is not used inside "act()", deadlocking should be minimized as well.
Actors should be wary of any blocking processing done while handling messages. Since actors process their messages sequentially, any time they are blocked waiting for I/O inside "act()", they can not process any other messages in their mailboxes. The Scala idiom to use here is to start another ad-hoc actor that does the actual blocking operation. This anti-pattern affects event-based(react) actor even more because it blocks the thread the event-based actor is piggy-backed on as well.
From what I can gather, all four of your calls to the service components are potentially blocking, so cares should be taken to make them scale when converting them to actors.