Move inlined example to its own class (#22453)
Issue: #22453 Mode inlined example for Shared Mutable State to its own class Add additional wrong case when the message is mutable Includes auto reformated code
This commit is contained in:
parent
0367812e40
commit
5102d14168
4 changed files with 87 additions and 35 deletions
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2017 Lightbend Inc. <http://www.lightbend.com>
|
||||
*/
|
||||
package docs.actor
|
||||
|
||||
class SharedMutableStateDocSpec {
|
||||
|
||||
//#mutable-state
|
||||
import akka.actor.{ Actor, ActorRef }
|
||||
import akka.pattern.ask
|
||||
import akka.util.Timeout
|
||||
import scala.concurrent.Future
|
||||
import scala.concurrent.duration._
|
||||
import scala.language.postfixOps
|
||||
import scala.collection.mutable
|
||||
|
||||
case class Message(msg: String)
|
||||
|
||||
class EchoActor extends Actor {
|
||||
def receive = {
|
||||
case msg => sender() ! msg
|
||||
}
|
||||
}
|
||||
|
||||
class CleanUpActor extends Actor {
|
||||
def receive = {
|
||||
case set: mutable.Set[_] => set.clear()
|
||||
}
|
||||
}
|
||||
|
||||
class MyActor(echoActor: ActorRef, cleanUpActor: ActorRef) extends Actor {
|
||||
var state = ""
|
||||
val mySet = mutable.Set[String]()
|
||||
|
||||
def expensiveCalculation(actorRef: ActorRef): String = {
|
||||
// this is a very costly operation
|
||||
"Meaning of live is 42"
|
||||
}
|
||||
|
||||
def expensiveCalculation(): String = {
|
||||
// this is a very costly operation
|
||||
"Meaning of live is 42"
|
||||
}
|
||||
|
||||
def receive = {
|
||||
case _ =>
|
||||
|
||||
//Wrong ways
|
||||
implicit val ec = context.dispatcher
|
||||
implicit val timeout = Timeout(5 seconds) // needed for `?` below
|
||||
|
||||
// Very bad, shared mutable state,
|
||||
// will break your application in weird ways
|
||||
Future { state = "This will race" }
|
||||
((echoActor ? Message("With this other one")).mapTo[Message])
|
||||
.foreach { received => state = received.msg }
|
||||
|
||||
// Very bad, shared mutable object,
|
||||
// the other actor cand mutate your own state,
|
||||
// or worse, you might get weird race conditions
|
||||
cleanUpActor ! mySet
|
||||
|
||||
// Very bad, "sender" changes for every message,
|
||||
// shared mutable state bug
|
||||
Future { expensiveCalculation(sender()) }
|
||||
|
||||
//Right ways
|
||||
|
||||
// Completely safe, "self" is OK to close over
|
||||
// and it's an ActorRef, which is thread-safe
|
||||
Future { expensiveCalculation() } foreach { self ! _ }
|
||||
|
||||
// Completely safe, we close over a fixed value
|
||||
// and it's an ActorRef, which is thread-safe
|
||||
val currentSender = sender()
|
||||
Future { expensiveCalculation(currentSender) }
|
||||
}
|
||||
}
|
||||
//#mutable-state
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue