Writing applications with Scala actors in practice II [closed] - scala

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.

Related

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.")
}

How to dynamically check type of an actor

It is a general question about developing with akka actor system.
I know, it sacrifices static type checking for greater flexibility, that is not the problem. Java does the same thing all the way.
But I'd like at least to check compatibility of ActorRefs dynamically. I searched for some method like actorRef.asInstanceOf[ActorType]. Such method should provide validation for an actorRef passed through messages. And it would allow safe application development. But I've found no method to do any kind of type check. Its even impossible to check if an actorRef correspond to given Props.
How this task typically solved in akka application? Are there any third-party tools for dynamic checks?
The purpose of ActorRef is to completely abstract the recipient. Sending a message to it provides absolutely no guarantees about a response or even suitability of the message being sent. The recipient could drop the message, route it, stash it or handle it. Any contract about handling and causing possible response messages to be emitted is entirely an informal agreement.
Now, that sounds like a lot to give up in a statically typed environment, but it provides a programming model that brings its own slew of advantages which by their design require that you are sending and receiving messages with the assumption that the messages will be handled but without any knowledge where or when they will be handled.
Regarding how this task is typically solved in akka applications is by configuration and/discovery. The contract of acceptable Messages is usually placed into a Protocol object, while the valid recipient for those Messages is either injected into the calling Actor at creation or queryable via some DiscoveryProtocol (itself hidden behind an ActorRef)
Let's say you have a UserRepository you want to query, you would create protocol like this:
case class User(id: Int, ... )
object UserRepositoryProtocol {
case class GetUser(userId: Int)
}
Further, let's assume that the ActorRef of UserRepository was not injected, but because it is just one of many services your actor might use has to be discovered via a general Discovery service:
object DiscoveryProtocol {
case class Discover(type: String)
case class Discovered(type: String, ref: ActorRef)
}
Now you can fetch a user like this:
(discoveryRef ? Discover("UserRepository")).flatMap {
case Discovered("UserRepository",repository) =>
(repository ? GetUser(id)).map {
case user:User => // do something with the user
}
}
The above condenses discovery and calls into a chain of ask operations. Chances are you would want to cache the discovered ref and or hand off the retrieved user to some other Actor that's doing the work, breaking each '?' into a ! and a matching receive in the same or different actor.
This last point illustrates the power of the actor model. In a traditional request => response model, the requestor and recipient of the response would have to be the same just by virtue of function signatures, but in the actor model, you can send from one actor, spawn a worker that will handle the response, etc.
Assume that an actor is not only encapsulated behind an actor ref, but that the physical location of an actor is also unknown. An actor can be running on another physical server or VM. You can't call instanceOf on an object in another VM - how can you expect to get the class of an actor then?
Now, when building, I would recommend you consider that all actors are remote via Akka's location transparency. (http://doc.akka.io/docs/akka/snapshot/general/remoting.html) If you assume all actors are remote, suddenly you'll think about your designs a little differently. Think of Akka as a Distribution Toolkit - that is its primary benefit!
If you're trying to reflect on actors during runtime, then there is probably something wrong with your design. Instead, you need to know what messages actors can accept and respond to.
If you really want to know what an actor can and can't do, then you could think of modelling some sort of "Accepts" method where an actor would reply with the current version of the described API that the actor implements for example - in this way your client and server can talk back and forth about what capabilities etc are supported dynamically during runtime.
I hope that contributes something to the discussion - just remember to always think of an actor as something that's running somewhere else and you'll design appropriately. The benefit of doing so is that you'll be able to scale out your applications with very minimal effort if your user base unexpectedly explodes!

How do you know what messages you can send to actor?

Is there any standard way of formalizing my scala/akka actor api? Imho, situation where I need to look into implementation to know what to send is not really a good option. Also, if implementation has changed and my message is no longer valid(not invoking action I think it invokes) I don't get any warning or error.
This is a question that is discussed very much in the community. I heard that maybe Akka 3 will have better support for typesafe actors, but that is some time down the road.
In the mean time you could use TypedActors, though the general suggestion is to use them at the boundaries of your application.
A nice approach that does not give you any typesafety, but makes the contract of an actor more visible, is to define the messages an actor can receive in their companion object. This way each time you want to send a message to an actor you choose from the message its companion object defines. This of course works best if you have specific messages for each actor. If you change the implementation you could remove the old message and add a new one, so that everyone who wanted to use the old implementation would get compiler errors.
Lastly there was a nice pattern last week on the mailing list. He creates traits to define the contracts for the actors and their consumers, but you still need to take care that the consumer mix in the correct trait.
In my experience, the best way to make sure everything works is an extensive test suite which will test each actor for itself, but also the communication between specific actors.
The approach generally taken in Erlang is to avoid sending messages to a process directly, and to provide additional API in the same module which defines the behavior of the process. In Akka it would look like
class Foo extends Actor {
// handles messages Bar(x: Int) and Baz
}
object Foo {
def bar(foo: ActorRef, x: Int) = foo ! Bar(x)
def baz(foo: ActorRef) = (foo ? Baz).mapTo[TypeOfResponseToBaz]
}
One problem is handling return messages, since Erlang generally promotes more synchronous style than Akka does. This may be handled by a naming convention (e.g. BarResponse or FooBarResponse if different actors handle the same message with different responses).

What is the best way to implement a request/response protocol using akka and scala?

I've been studying about how I could develop a distributed architecture that implements the protocol request/response using the concept of concurrency through actors.
I concluded that the best way to do this is by creating a response system with synchronous handling of Futures/Promises, and soon after the response, leaving an open channel to receive notifications.
Thus an architecture that would work exactly like a inbox message.
It has some problems.
Thus I would have to maintain two endpoints (actors in the two layers)?
The Problem:
The view module requests that a particular element is processed. She sends this command to be processed via RemoteActor on the application server. This server should immediately return the promise that it will notify you when the element is processed. After this, the view module will be waiting the notification of completion of processing.
How do you see this problem?
I am using Scala, Akka and Google Guice.
I believe it is a generic problem that everyone can make use of their solutions. Excuse me if I'm hurting the terms of stackoverflow site.
Thanks in advance
I don't want to distract from any good answers you may get on Akka, because I unfortunately don't know much about Akka and it's distributed actors features, but I'd like to ask if you've considered any alternatives.
It seems that you basically need an asynchronous RPC library. There are two powerful libraries written in Scala that I know of that may satisfy your requirements - http://sna-projects.com/norbert/ and http://twitter.github.com/finagle/. Finagle gives some really powerful combinators for expressing asynchronous computation dependencies and registering listeners on futures. I'm currently maintaining Norbert, which we use at LinkedIn for some of our distributed systems, such as search.
//On "server" node
class SomeActor extends Actor {
def receive = {
case messageToRemoteActor => self reply_? TypeOfResponseMessage()
}
}
Actor.remote.register("myRemoteActor", actorOf[SomeActor])
//On "client" node
val remoteActor = Actor.remote.actorFor("myRemoteActor", "hostnameOrIpOfNodeContainingTheActorAbove", port)
val f: Future[TypeOfResponseMessage] = remoteActor !!! messageToRemoteActor
f.onComplete( _.value.get match {
case Left(exception) => handle(exception)
case Right(result) => handle(result)
})
Why not just use one of 0MQ's REQ-REP sockets?
https://github.com/zcox/akka-zeromq-java
That way you solve your immediate problem and at the same time, begin learn an architecture that will take you a long way and supports communications with clients written in many languages.
For an example of where this might lead look at http://blog.getintheloop.eu/2009/05/22/lift-amqp-with-rabbitmq-and-scala-tutorial-and-screencast/
Note that I am NOT suggesting that you use AMQP today since a RabbitMQ broker would be overkill for your immediate problem. Rather, I am suggesting that you invest your time in using an architecture (message queueing) that will pay you dividends in the long run.

Scala actors - worst practices? [closed]

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.