Fixed a critical mistake
Erroneously used functional actor for mutable state. Changed actor style to OO from functional. Experimented with ask pattern to get final result
This commit is contained in:
parent
260aa0fdc4
commit
1abc30070c
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.ammonite
|
||||
.metals
|
55
ActorDemo.sc
55
ActorDemo.sc
@ -13,35 +13,47 @@ import akka.util.Timeout
|
||||
import scala.concurrent.duration._
|
||||
import akka.actor.typed.scaladsl.AskPattern._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import akka.actor.typed.scaladsl.AbstractBehavior
|
||||
import akka.actor.typed.scaladsl.ActorContext
|
||||
import scala.util.Success
|
||||
import scala.util.Failure
|
||||
import scala.concurrent.Await
|
||||
import scala.concurrent.Future
|
||||
|
||||
object CounterActor {
|
||||
final case class CounterResult(count: Int)
|
||||
|
||||
sealed trait Command
|
||||
final case object IncCount extends Command
|
||||
final case class CounterResult(count: Int)
|
||||
final case class GetResult(sender: ActorRef[RootActor.Command])
|
||||
extends Command
|
||||
|
||||
var counter = 0
|
||||
final case class GetResult(sender: ActorRef[CounterResult]) extends Command
|
||||
|
||||
def apply(): Behavior[Command] =
|
||||
Behaviors.receive { (context, command) =>
|
||||
command match {
|
||||
case IncCount => counter += 1
|
||||
Behaviors.setup(ctx => new CounterActor(ctx))
|
||||
|
||||
private class CounterActor(context: ActorContext[Command])
|
||||
extends AbstractBehavior[Command](context) {
|
||||
private var counter = 0 // encapsulated mutable state
|
||||
override def onMessage(msg: Command): Behavior[Command] = {
|
||||
msg match {
|
||||
case IncCount =>
|
||||
counter += 1
|
||||
Behaviors.same
|
||||
case GetResult(sender) =>
|
||||
context.log.info(s"Value of counter is $counter");
|
||||
sender ! RootActor.Reply(counter)
|
||||
}
|
||||
|
||||
sender ! CounterResult(counter)
|
||||
Behaviors.same
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object RootActor {
|
||||
sealed trait Command
|
||||
case class Reply[T](reply: T) extends Command
|
||||
case object Begin extends Command
|
||||
case object GetResult extends Command
|
||||
final case class Reply[T](reply: T) extends Command
|
||||
final case object Begin extends Command
|
||||
final case class GetResult(repyTo: ActorRef[CounterActor.CounterResult])
|
||||
extends Command
|
||||
|
||||
implicit val timeout: Timeout = 3.seconds
|
||||
|
||||
@ -63,10 +75,11 @@ object RootActor {
|
||||
counterActor ! CounterActor.IncCount
|
||||
counterActor ! CounterActor.IncCount
|
||||
|
||||
case GetResult =>
|
||||
case GetResult(replyTo) =>
|
||||
counterActor ! CounterActor.GetResult(
|
||||
context.self
|
||||
replyTo
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
Behaviors.same
|
||||
@ -77,13 +90,15 @@ object RootActor {
|
||||
|
||||
@main
|
||||
def main() = {
|
||||
implicit val rootActor =
|
||||
implicit val system =
|
||||
ActorSystem(RootActor(), "TestActors")
|
||||
|
||||
implicit val timeout: Timeout = 3.seconds
|
||||
|
||||
rootActor ! RootActor.Begin
|
||||
rootActor ! RootActor.GetResult
|
||||
system ! RootActor.Begin
|
||||
// system ! RootActor.GetResult
|
||||
|
||||
Thread.sleep(1000)
|
||||
val x: Future[CounterActor.CounterResult] =
|
||||
system ? (ref => RootActor.GetResult(ref))
|
||||
Await.result(x, 1.second)
|
||||
}
|
||||
|
10
README.md
10
README.md
@ -3,15 +3,15 @@
|
||||
An experiment to see how the actor model can be used to synchronize / encapsulate mutable state without the use of locks.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
./ActorsDemo.sc
|
||||
```
|
||||
|
||||
Sample output:
|
||||
```
|
||||
22:11:47.473 [TestActors-akka.actor.default-dispatcher-3] INFO ammonite.$file.ActorDemo$RootActor$ - --- Beginning ---
|
||||
|
||||
22:11:47.475 [TestActors-akka.actor.default-dispatcher-6] INFO ammonite.$file.ActorDemo$CounterActor$ - Value of counter is 5
|
||||
|
||||
22:11:47.475 [TestActors-akka.actor.default-dispatcher-3] INFO ammonite.$file.ActorDemo$RootActor$ - Received message Reply(5)
|
||||
```
|
||||
13:02:58.966 [TestActors-akka.actor.default-dispatcher-3] INFO ammonite.$file.AkkaActorsDemo.ActorDemo$RootActor$ - --- Beginning ---
|
||||
13:02:58.967 [TestActors-akka.actor.default-dispatcher-5] INFO ammonite.$file.AkkaActorsDemo.ActorDemo$CounterActor$CounterActor - Value of counter is 5
|
||||
CounterResult(5)
|
||||
```
|
Loading…
Reference in New Issue
Block a user