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:
Josep Prat 2017-03-05 14:39:37 +01:00
parent 0367812e40
commit 5102d14168
4 changed files with 87 additions and 35 deletions

View file

@ -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
}