I am working on a Logic Circuit implementation with scala using akka and I need to implement a wire Actor (for example for an component actor such as an AND gate) :
The wire should transport a signal, true or false.
It's great that you're learning akka, the task is a good place to start.
A couple of things before we start - your current code and modelling may be questioned in a few places.
Why does AddComponent need a wireName? Do you plan to find wires by their actor name? Usually we use ActorRefs instead of their names.
Also why does StateChange need a wireName? Does it really matter? I would say state propagation could be done using simple messages: StateChanged(state: Boolean)
I don't think there's any benefit in storing names of actors since a set of their ActorRefs is fine.
It's not usually a good idea to just handle primitive types like current: Boolean, we like to give semantic meaning to our messages as you did with StateChange so I would use that here also.
Some code I came up with:
import akka.actor.{ActorLogging, Actor, ActorRef}
case class AddComponent(actor: ActorRef)
case class StateChange(state: Boolean)
class Wire(var currentState: Boolean) extends Actor with ActorLogging {
var connections = Set.empty[ActorRef]
def receive: Actor.Receive = {
case AddComponent(actor) =>
connections += actor
case StateChange(state) =>
currentState = state
val connectionsToPropagateTo = connections - sender // Don't propagate back to sender
connectionsToPropagateTo.foreach { component =>
component ! StateChange(currentState) // Send the component a StateChange message.
}
}
}
You can simply extend this with RemoveComponent and other stuff as needed.
Related
The Akka Typed Actors documentation states that it will be superseded by Akka Typed. I am inferring from this that Akka Typed can be used to implement the Active Object pattern; but it is not too clear to me how. Here is my attempt so far; I'm aware it stinks :D
object HelloWorld {
final case class Greet(whom: String, replyTo: ActorRef[Greeted])
final case class Greeted(whom: String)
private val greeter = Static[Greet] { msg ⇒
println(s"Hello ${msg.whom}!")
msg.replyTo ! Greeted(msg.whom)
}
private val system = ActorSystem("HelloWorld", Props(greeter))
def greet(whom: String): Future[Greeted] = system ? (Greet(whom, _))
}
Cheers
The Active Object Pattern as defined by the page you link to is not desirable for all the reasons why TypedActors are being removed: the fact that a method is executed asynchronously is so important that it should not be hidden by technologies like proxy objects that implement normal interfaces. Instead, Akka Typed allows you to write nearly the same code as if it was an Active Object while retaining the asynchronous marker: instead of selecting a method with the . syntax you send a message using ? (or ! if the protocol is not simple request–response). Your example would look like this:
object HelloWorld {
final case class Greet(whom: String)(replyTo: ActorRef[Greeted])
final case class Greeted(whom: String)
val greeter = Static[Greet] { msg ⇒
println(s"Hello ${msg.whom}!")
msg.replyTo ! Greeted(msg.whom)
}
}
object Sample extends App {
import HelloWorld._
val system = ActorSystem("HelloWorld", Props(greeter))
val fg = system ? Greet("John")
}
Please note that creating a separate thread (or ActorSystem) per object may sound okay as per the classical pattern, but doing that foregoes many of the benefits of a message-driven architecture, namely that many Actors can share the same resources for more efficient execution and they can form supervision hierarchies for principled failure handling etc.
I use IntelliJ IDEA, but the question could relate to other IDEs. There is a great way to navigate the code with Ctrl+click. From the method call it jumps to the method declaration. It really boosts the productivity.
Actor systems are based on message passing. Example in Akka with Scala:
class MyMessage
object MyMessage
class MyActor1 extends Actor {
context.actorOf(Props[MyActor2]) ! MyMessage
}
class MyActor2 extends Actor {
def receive = {
case MyMessage =>
...
}
}
Is there a way to navigate in code between sending the message and receiving the message?
I mean clicking on ! will take me to the definition of ! method in ScalaActorRef, but that's 99% chance that I don't want that. Jumping to the corresponding receive method (or, if possible, to correct case: case MyMessage) would be more appropriate.
How do you navigate the code between actors?
I don't think it is possible in general because an actor can change its behavior at runtime, including what messages it can process - as opposed to methods which can be statically indexed. For example, receive function may be computed depending on the actor state:
class MyActor extends Actor {
var i = 0
def receive = firstReceive
def commonReceive = {
case Increment =>
i += 1
if (i % 3 == 0) context.become(firstReceive)
else context.become(secondReceive)
}
def firstReceive = commonReceive orElse {
case Ping =>
sender ! "zero"
}
def secondReceive = commonReceive orElse {
case Ping =>
sender ! "one or two"
}
}
Now the actor handles messages differently depending on which messages it handled before. And this is only a simple example - actual actor behavior may even be received from the outside!
case class Behavior(receive: Actor.Receive)
class MyActor extends Actor {
def receive = {
case Behavior(r) => context.become(r)
}
}
Another difficulty which is even greater is that you usually have an ActorRef to which you send messages with !. This ActorRef has no static connection with the actor class which contains message handling logic - it is instantiated with Props which can use arbitrary code to determine which actor class should be used:
val r = new Random
val a = actorSystem.actorOf(Props(if (r.nextInt(100) > 50) new FirstActor else new SecondActor))
a ! Message // which handler should this declaration lead to?
This makes finding actual message handler next to impossible.
If you think that it may be worth it to support simpler cases, like the one you provided, you can always submit a feature request to YouTrack.
Not perfect, but what could help would be to use Find Usage (Alt+F7) on the type of the message. For that you probably have to navigate to the type Declaration (Ctrl+Shift+B) first
I wonder if there is an easy way to create a shortcut for the combination.
Another idea would be to use the Structural Search which might be able to find things like excpressions, that match on the class name ...
Once you created a template to your liking you can then record a macro
I'm developing an application using Akka, and a thing that kind of bugs me the whole time regards message declaration with the Actor's. Where should I declare the messages? In the receivers companion object or the senders companion object or on some third place?
The Akka team recommends Message should be defined in the same place the props method should be: in the Receiver's Companion object because the Receiver implements the receive partial function and needs to know about all the messages it supports. Also, multiple senders can send a set of messages (implemented by the Receiver), so you cannot put it in one single sender.
If the official Typesafe Activator template activator-akka-scala-seed is of any importance regarding Akka's good practices the messages should be part of companion object as shown in the following PingActor actor (copied directly from the template):
package com.example
import akka.actor.{Actor, ActorLogging, Props}
class PingActor extends Actor with ActorLogging {
import PingActor._
var counter = 0
val pongActor = context.actorOf(PongActor.props, "pongActor")
def receive = {
case Initialize =>
log.info("In PingActor - starting ping-pong")
pongActor ! PingMessage("ping")
case PongActor.PongMessage(text) =>
log.info("In PingActor - received message: {}", text)
counter += 1
if (counter == 3) context.system.shutdown()
else sender() ! PingMessage("ping")
}
}
object PingActor {
val props = Props[PingActor]
case object Initialize
case class PingMessage(text: String)
}
Note PingActor that holds all the accepted messages by the actor (as you may've noticed it's not followed strictly since PongActor.PongMessage is also accepted, but not defined in the companion object PingActor).
From another question How to restrict actor messages to specific types? the Viktor said:
The common practice is to declare what messages an Actor can receive
in the companion object of the Actor, which makes it very much easier
to know what it can receive.
I am trying to use a broadcast router in Scala, if I'm not mistaken it should look like this:
val system = ActorSystem("My beautiful system")
val workerRouter = system.actorOf(Props[Agent].withRouter(BroadcastRouter(individualDefinitions.size)), name = "agentRouter")
That is what I understand from the tutorial I am following.
The workerRouter acts as another actor and I can send messages to this router that will send them to all the Agents (as many as individualDefinitions I have).
The problem is that I'd like to use the individual definitions to build the agents, they actually take some parameters in the constructor and those parameters are in the individualDefinitions.
Q: How could I tell the router to pass those parameters to each one of them as part of the constructor?
Please note each actor should get one individualDefinition and they are all different. I cannot use the solution in a related question where the constructor receives constants: In Akka Java actor model, can a router create actors with non-default constructor?
Please note that here each actor should have different parameters, if one of them is restarted it should get the same parameters it got in the first place. I don't know if that solution could be modified to do that.
A possible solution could be using an actor as the router, to separate creation (constructor) and routing, as in question Akka (java), non blocking broadcast to all children.
I'm not sure that is the "right" approach in this case. Using an actor as the router has several problems (besides of elegance). I am concerned about the actor that works as a router being restarted and losing all its subscribers. If the actor is restarted in half of a loop some actors could also miss some messages if I'm not mistaken.
Thank you.
You can create routers by specifying as routees some already created actors, constructed by whatever logic.
The following example will create 2 actors created differently and then create a round robin router which will route the messages to them.
class MyActor(param1: String) extends Actor with ActorLogging {
def receive: Actor.Receive = {
case msg => log.info("Message from {}: {}", param1, msg)
}
}
object MyActor {
def apply(param: String): Props = Props(new MyActor(param))
}
object Main extends App {
val system = ActorSystem()
val a1 = system.actorOf(MyActor("actor1"))
val a2 = system.actorOf(MyActor("actor2"))
val routerProps = Props.empty.withRouter(RoundRobinRouter(routees = Vector(a1, a2)))
val router = system.actorOf(routerProps)
for (i <- 1 to 10) {
router ! i
}
readLine()
system.shutdown()
}
More details here: http://doc.akka.io/docs/akka/2.2.0/scala/routing.html
public class Master extends UntypedActor {
-----
-----
public Master() {
workerRouter = this.getContext().actorOf(Worker.createWorker().withRouter(new RoundRobinRouter(8)), "workerRouter");
}
With Akka 2.4.2, we can simply use:
workerRouter = this.getContext().actorOf(new RoundRobinPool(noOfWorkers).props(Props.create(Worker.class)), "workerRouter");
This is best Effort code executed in min. time in akka .
I am playing around with Scala right now and tried to figure out some best practices about how to design classes. (Trying Scala since a week or so.)
Since my Erlang time I am a huge fan of message passing and actor based software. In most Scala examples actor classes are implemented like this:
object Foo
object Bar
class MyActor extends Actor {
def receive = {
case Foo => ...
case Bar => ...
case _ => ...
}
}
But what I learned from my object oriented (interfaces and polymorphism) carrier tells me that this concept is not very flexible.
MyActor could be replaced by MyAdvancedActor but there is no contract which defines which messages an MyActor implementation needs to implement.
When I think about writing Actors in Scala I tend to write a trait which specifies some methods. The MyActor implementation needs to implement this methods in which the can send its own private messages to itself.
With this approach we have a specified interface and can replace the MyActor implementation in a type-safe manner.
In my time of reading scala tutorials and examples I did not come across such an class design. Is it not common sense or are there better ways in doing this in Scala? Or are these tutorials just to small to cover such a topic?
Common practice is to use an algebraic data type in such cases: you could create a sealed base type for all messages like this:
sealed trait MyActorMessages
object Foo extends MyActorMessages
object Bar extends MyActorMessages
But this kind of contract is not enforced by compiler. You could use use Typed Channels to enforce this contract:
class MyActor extends Actor with Channels[TNil, (MyActorMessages, MyActorReply) :+: TNil] {
channel[MyActorMessages] { (req, snd) ⇒
req match {
case Foo ⇒ ...
case Bar ⇒ ... // You'll get a warning if you forget about `Bar`
}
}
}
Compiler will force you (with warning) to process all possible message types (in this case all subtypes of MyActorMessages), and senders will be forced to send only valid messages using <-!- method (with compilation error).
Note that senders can also use unsafe method ! to send invalid messages.
I really like the solution from #senia. It's an effective use of Akka's new Typed Channels feature. But if that solution does not suit you, I can offer something a bit more traditional to the OO world. In this solution you specify the actual message handling behavior for the actor via a strategy implementation that the actor is constructed with. The code would look something like this:
//Strategy definition
trait FooStrategy{
def foo1(s:String):String
def foo2(i:Int):Int
}
//Regular impl
class RegularFoo extends FooStrategy{
def foo1(s:String) = ...
def foo2(i:Int) = ...
}
//Other impl
class AdvancedFoo extends FooStrategy{
def foo1(s:String) = ...
def foo2(i:Int) = ...
}
//Message classes for the actor
case class Foo1(s:String)
case class Foo2(i:Int)
//Actor class taking the strategy in the constructor
class FooActor(strategy:FooStrategy) extends Actor{
def receive = {
case Foo1(s) => sender ! strategy.foo1(s)
case Foo2(i) => sender ! strategy.foo2(i)
}
}
Then to create instances of this actor:
val regFooRef = system.actorOf(Props(classOf[FooActor], new RegularFoo))
val advFooRef = system.actorOf(Props(classOf[FooActor], new AdvancedFoo))
One benefit here is that you are decoupling the business logic of the actor from it's normal message handling behavior. You are letting the actor class just do actor stuff (receive from mailbox, reply to sender, etc...) and then the real business logic is encapsulated in a trait. This also makes it much easier to test the business logic in isolation with unit tests for the trait impls. If you needed actor type stuff in the trait impls, then you could always specify an implicit ActorContext to the methods on FooStrategy, but then you would lose the complete decoupling of actor and business logic.
Like I said earlier, I like the solution from #senia; I just wanted to give you another option that might be more traditional OO.