What mechanism use an Akka Actor to persist its messages? - scala

Tha Akka documentaton indicates:
A durable mailbox is a replacement for the standard actor mailbox that
is durable.
What is the mechanism used as a standard mailbox so an Actor can read its messages after a restart?
Thank you.

I've implemented a small project to check this out with my own hands.
The configuration of an Actor's mailbox is achieved via the dispatcher. The following are the possibilities for the mailbox:
UnboundedMailbox
BoundedMailbox
UnboundedPriorityMailbox
BoundedPriorityMailbox
and finally:
Durable mailboxes
I had to configure my actor system with a dispatcher which indicates that the mailbox is file based. The following lines were just neccesary in the configuration of the Actor System:
my-dispatcher {
mailbox-type = akka.actor.mailbox.FileBasedMailboxType
}
In adition, I configured the properties for the file based durable mailbox, with the indications provided in:
http://doc.akka.io/docs/akka/2.0.3/modules/durable-mailbox.html
Finally, the creator of the specific Actor I wanted to persist in a file creates the Actor with the following:
context.actorOf(Props[MyActor].withDispatcher("my-dispatcher"), "myactor1"
I still need more practice to make an Actor to be recreated and read the remaining messaged in the mailbox, but the main question is answered now.
Everything was found in the documentation, it was just a matter of getting things done.

Related

Access AKKA mailbox object in Actor

I'm using a custom mailbox with my Akka actor. My class looks something like this:
MyActor extends Actor with RequiresMessageQueue[DRMailbox]{ ... }
How can I access the DRMailbox object in Akka actor? I have implemented some methods in DRMailbox which I want to share with my Akka actor.
This doesn't seem possible, by design. From the documentation:
An important feature in which Akka differs from some other actor model
implementations is that the current behavior must always handle the
next dequeued message, there is no scanning the mailbox for the next
matching one. Failure to handle a message will typically be treated as
a failure, unless this behavior is overridden.
If you are really trying to access the mailbox from within an Actor then this suggests that you may be misusing the Actor pattern and should reconsider your design...

How to test an actor?

How can I test an actor? Since the calls are not synchronous, and one messages can cause multiple messages to be sent, what are the ways of testing it?
E.g. How can I test that my actor sent 3 messages in response to another message?
In general you cannot test what an actor has done unless it interacts with a trait or interface you provide in the construction or in an input message. So if you have an actor like the following.
actor MyActor
be do_stuff(receiver: MyReceiver)
You use a pattern where you combine a timer, for a timeout, and a wrapper actor that provides MyReceiver to test if the actor actually did send the message or sequence of messages that where expected.
Pony already includes the ponytest package with some support for this kind of tests. You can check the PonyTest actor at GitHub. Basically you have to specify a timeout and ensure one of your actors calls complete in the test helper for success. Note that the API has changed since the last stable version.

Send message to existing Actor in different project

I am wondering if it is possible to send message to an existing Actor from another project?
Existing Actor & allowed Messages:
package org.x.y.z
private case object MA
private case object MB
private class ExistActor extends Actor {
def receive: Receive = {
case MA =>
case MB =>
}
}
However my current project is different from the above, it's org.w.h.i, for example.
Suppose I know the actorSystem name, url and everything that is needed to construct an ActorSelection of org.x.y.ExistActor, So is it possible to send a message and get results?
Note the allowed message of org.x.y.ExistActor and itself are all private, if I am sending a message, I would make a local copy of allowed messages.
Yes, if both systems are set up for remoting you can send a message to any actor that you know the path for using ActorSelection.
However, unless your remote actor system is able to send messages that your actor will respond do, addressing it (as in your example) will be pointless.
First of all Akka Remoting should be enabled on both JVMs obviously. Once you successfully get ActorSelection you can send messages to that actor. It does not matter whether the actor is defined as private class. All that matters that it's running and accessible.
Now the question is whether the actor would accept the messages that you send and whether you can construct these messages since they are private in your case.
It all depends on a serializer configured for Akka Remoting. See these docs for config options and check whether remote project uses serializer that does not depend on Java serialization or any class version specific serialization.
By default Akka Remoting uses Protocol Buffers so that should allow you to construct messages of exactly same type and shape on your side and send them over successfully.

What is the best way to get a reference to an Akka Actor

I am a little confused by how I am supposed to get a reference to my Actor once it has been crerated in the Akka system. Say I have the following:
class MyActor(val x: Int) extends Actor {
def receive = {
case Msg => doSth()
}
}
And at some stage I would create the actor as follows:
val actorRef = system.actorOf(Props(new MyActor(2), name = "Some actor")
But when I need to refer to the MyActor object I cannot see any way to get it from the actor ref?
Thanks
Des
I'm adding my comment as an answer since it seems to be viewed as something worth putting in as an answer.
Not being able to directly access the actor is the whole idea behind actor systems. You are not supposed to be able to get at the underlying actor class instance. The actor ref is a lightweight proxy to your actor class instance. Allowing people to directly access the actor instance could lead down the path of mutable data issues/concurrent state update issues and that's a bad path to go down. By forcing you to go through the ref (and thus the mailbox), state and data will always be safe as only one message is processed at a time.
I think cmbaxter has a good answer, but I want to make it just a bit more clear. The ActorRef is your friend for the following reasons:
You cannot ever access the underlying actor. Actors receive their thread of execution from the Dispatcher given to them when they are created. They operate on one mailbox message at a time, so you never have to worry about concurrency inside of the actor unless YOU introduce it (by handling a message asynchronously with a Future or another Actor instance via delegation, for example). If someone had access to the underlying class behind the ActorRef, they could easily call into the actor via a method using another thread, thus negating the point of using the Actor to avoid concurrency in the first place.
ActorRefs provide Location Transparency. By this, I mean that the Actor instance could exist locally on the same JVM and machine as the actor from which you would like to send it a message, or it could exist on a different JVM, on a different box, in a different data center. You don't know, you don't care, and your code is not littered with the details of HOW the message will be sent to that actor, thus making it more declarative (focused on the what you want to do business-wise, not how it will be done). When you start using Remoting or Clusters, this will prove very valuable.
ActorRefs mask the instance of the actor behind it when failure occurs, as well. With the old Scala Actors, you had no such proxy and when an actor "died" (threw an Exception) that resulted in a new instance of the Actor type being created in its place. You then had to propagate that new instance reference to anyone who needed it. With ActorRef, you don't care that the Actor has been reincarnated - it's all transparent.
There is one way to get access to the underlying actor when you want to do testing, using TestActorRef.underlyingActor. This way, you can write unit tests against functionality written in methods inside the actor. Useful for checking basic business logic without worrying about Akka dynamics.
Hope that helps.

Actor addresses and tests

I'm building up an actor hierarchy in which some actors reply to messages they get directly to a well-known actor (fixed name). I.e. these actors (far-removed in the hierarchy) obtain an actorRef via context.actorFor("akka://...").
I.e. for example, I have an "orchestrating" actor:
system.actorOf(Props[OrchestratingActor], name = "orchestrator")
which will then have an address of the kind akka://application/user/orchestrator
and someplace else, a random worker that received a message and wants to talk to the orchestrator:
class RandomWorker extends Actor {
def theOrchestrator = context.actorFor("akka://application/user/orchestrator")
def receive = {
case Foo =>
theOrchestrator ! "Bar"
}
}
Now, I'd like to test those actors and am wondering about how to deal with those addresses: when unit-testing an actor (e.g. using TestActorRef), how do I go about checking what's being sent to the remote address? One idea would be to (when possible) provide the address to the well-known actor via the constructor, and pass in the address of a TestActor to see what's being received. However I wonder if there isn't a way to "impersonate" a given address in the test, esp. in situation where the addresses aren't simple.
In other words I'd like to test the behavior of the actor (will it indeed have sent "Bar" to the orchestrator upon receiving a Foo
My recommendation would be to avoid using look-ups of actors for the purpose you show. It is rather a tool for the setup phase of your application, when wiring it all together. But even then most actors’ supervisors will know the dependencies of their children without using look-ups.
Within a local actor system all ActorRefs can be injected top to bottom (using constructor arguments or introduction messages). Look-ups are most useful when introducing remote systems with each other.
There is nothing wrong with injecting the address via the constructor. Let it me know if you need any details, because at the moment I don't know how to make this more clear, since you basically answered your own question. And btw, I don't know, which Akka version you are using, but actorFor has been recently deprecated in favor of ActorSelection, and there are good reasons for this.