Skip to content

Commit

Permalink
Rename MutableBehavior to AbstractBehavior, akka#25750
Browse files Browse the repository at this point in the history
* Also cleanup javadsl Receive, which is only used from AbstractBehavior
* Clarify further in docs that the functional vs OO style is a matter of taste
  • Loading branch information
patriknw committed Oct 17, 2018
1 parent 1b6d185 commit ad3ad15
Show file tree
Hide file tree
Showing 22 changed files with 212 additions and 138 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class ReceiveBuilderTest extends JUnitSuite {

@Test
public void testMutableCounter() {
Behavior<BehaviorBuilderTest.CounterMessage> mutable = Behaviors.setup(ctx -> new MutableBehavior<BehaviorBuilderTest.CounterMessage>() {
Behavior<BehaviorBuilderTest.CounterMessage> mutable = Behaviors.setup(ctx -> new AbstractBehavior<BehaviorBuilderTest.CounterMessage>() {
int currentValue = 0;

private Behavior<BehaviorBuilderTest.CounterMessage> receiveIncrease(BehaviorBuilderTest.Increase msg) {
Expand All @@ -32,7 +32,7 @@ private Behavior<BehaviorBuilderTest.CounterMessage> receiveGet(BehaviorBuilderT
}

@Override
public Behaviors.Receive<BehaviorBuilderTest.CounterMessage> createReceive() {
public Receive<BehaviorBuilderTest.CounterMessage> createReceive() {
return receiveBuilder()
.onMessage(BehaviorBuilderTest.Increase.class, this::receiveIncrease)
.onMessage(BehaviorBuilderTest.Get.class, this::receiveGet)
Expand All @@ -41,24 +41,24 @@ public Behaviors.Receive<BehaviorBuilderTest.CounterMessage> createReceive() {
});
}

private static class MyMutableBehavior extends MutableBehavior<BehaviorBuilderTest.CounterMessage> {
private static class MyAbstractBehavior extends AbstractBehavior<BehaviorBuilderTest.CounterMessage> {
private int value;

public MyMutableBehavior(int initialValue) {
public MyAbstractBehavior(int initialValue) {
super();
this.value = initialValue;
}

@Override
public Behaviors.Receive<BehaviorBuilderTest.CounterMessage> createReceive() {
public Receive<BehaviorBuilderTest.CounterMessage> createReceive() {
assertEquals(42, value);
return receiveBuilder().build();
}
}

@Test
public void testInitializationOrder() throws Exception {
MyMutableBehavior mutable = new MyMutableBehavior(42);
MyAbstractBehavior mutable = new MyAbstractBehavior(42);
assertEquals(Behaviors.unhandled(), mutable.receive(null, new BehaviorBuilderTest.Increase()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ public OtherResponse(Backend.Response response) {
}
}

public static class Translator extends MutableBehavior<Command> {
public static class Translator extends AbstractBehavior<Command> {
private final ActorContext<Command> ctx;
private final ActorRef<Backend.Request> backend;
private final ActorRef<Backend.Response> backendResponseAdapter;
Expand All @@ -194,7 +194,7 @@ else if (rsp instanceof Backend.JobCompleted)
}

@Override
public Behaviors.Receive<Command> createReceive() {
public Receive<Command> createReceive() {
return receiveBuilder()
.onMessage(Translate.class, cmd -> {
taskIdCounter += 1;
Expand Down Expand Up @@ -522,7 +522,7 @@ public Behavior<HomeCommand> homeBehavior() {
}

// per session actor behavior
class PrepareToLeaveHome extends MutableBehavior<Object> {
class PrepareToLeaveHome extends AbstractBehavior<Object> {
private final String whoIsLeaving;
private final ActorRef<ReadyToLeaveHome> respondTo;
private final ActorRef<GetKeys> keyCabinet;
Expand All @@ -537,7 +537,7 @@ public PrepareToLeaveHome(String whoIsLeaving, ActorRef<ReadyToLeaveHome> respon
}

@Override
public Behaviors.Receive<Object> createReceive() {
public Receive<Object> createReceive() {
return receiveBuilder()
.onMessage(Wallet.class, (wallet) -> {
this.wallet = Optional.of(wallet);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@
import akka.actor.typed.ActorSystem;
import akka.actor.typed.Behavior;
import akka.actor.typed.Terminated;
import akka.actor.typed.javadsl.Behaviors;
import akka.actor.typed.javadsl.Behaviors.Receive;
import akka.actor.typed.javadsl.AbstractBehavior;
import akka.actor.typed.javadsl.ActorContext;
import akka.actor.typed.javadsl.MutableBehavior;
import akka.actor.typed.javadsl.Behaviors;
import akka.actor.typed.javadsl.Receive;
//#imports
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class MutableIntroTest {
public class OOIntroTest {

//#chatroom-actor
public static class ChatRoom {
Expand Down Expand Up @@ -89,7 +89,7 @@ public static Behavior<RoomCommand> behavior() {
return Behaviors.setup(ChatRoomBehavior::new);
}

public static class ChatRoomBehavior extends MutableBehavior<RoomCommand> {
public static class ChatRoomBehavior extends AbstractBehavior<RoomCommand> {
final ActorContext<RoomCommand> ctx;
final List<ActorRef<SessionCommand>> sessions = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
package akka.actor.typed

import akka.actor.typed.scaladsl.{ Behaviors SBehaviors }
import akka.actor.typed.scaladsl.{ MutableBehavior SMutableBehavior }
import akka.actor.typed.scaladsl.{ AbstractBehavior SAbstractBehavior }
import akka.actor.typed.javadsl.{ ActorContext JActorContext, Behaviors JBehaviors }
import akka.japi.function.{ Function F1e, Function2 F2, Procedure2 P2 }
import akka.japi.pf.{ FI, PFBuilder }
Expand Down Expand Up @@ -451,7 +451,7 @@ class MutableScalaBehaviorSpec extends Messages with Become with Stoppable {

def behv(monitor: ActorRef[Event]): Behavior[Command] =
SBehaviors.setup[Command] { ctx
new SMutableBehavior[Command] {
new SAbstractBehavior[Command] {
private var state: State = StateA

override def onMessage(msg: Command): Behavior[Command] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import java.io.IOException
import java.util.concurrent.atomic.{ AtomicBoolean, AtomicInteger }

import akka.actor.ActorInitializationException
import akka.actor.typed.scaladsl.{ Behaviors, MutableBehavior }
import akka.actor.typed.scaladsl.{ Behaviors, AbstractBehavior }
import akka.actor.typed.scaladsl.Behaviors._
import akka.testkit.EventFilter
import akka.actor.testkit.typed.scaladsl._
Expand Down Expand Up @@ -64,7 +64,7 @@ object SupervisionSpec {
Behaviors.same
}

class FailingConstructor(monitor: ActorRef[Event]) extends MutableBehavior[Command] {
class FailingConstructor(monitor: ActorRef[Event]) extends AbstractBehavior[Command] {
monitor ! Started
throw new RuntimeException("simulated exc from constructor") with NoStackTrace

Expand Down Expand Up @@ -257,7 +257,7 @@ class SupervisionSpec extends ScalaTestWithActorTestKit(

class FailingConstructorTestSetup(failCount: Int) {
val failCounter = new AtomicInteger(0)
class FailingConstructor(monitor: ActorRef[Event]) extends MutableBehavior[Command] {
class FailingConstructor(monitor: ActorRef[Event]) extends AbstractBehavior[Command] {
monitor ! Started
if (failCounter.getAndIncrement() < failCount) {
throw TE("simulated exc from constructor")
Expand Down Expand Up @@ -732,7 +732,7 @@ class SupervisionSpec extends ScalaTestWithActorTestKit(
}
}

"fail when exception from MutableBehavior constructor" in new FailingConstructorTestSetup(failCount = 1) {
"fail when exception from AbstractBehavior constructor" in new FailingConstructorTestSetup(failCount = 1) {
val probe = TestProbe[Event]("evt")
val behv = supervise(setup[Command](_ new FailingConstructor(probe.ref)))
.onFailure[Exception](SupervisorStrategy.restart)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package akka.actor.typed

import akka.Done
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.scaladsl.MutableBehavior
import akka.actor.typed.scaladsl.AbstractBehavior
import akka.actor.typed.scaladsl.adapter._
import akka.testkit.EventFilter
import akka.actor.testkit.typed.scaladsl.TestProbe
Expand All @@ -28,7 +28,7 @@ object WatchSpec {
case (_, Stop) Behaviors.stopped
}

val mutableTerminatorBehavior = new MutableBehavior[Stop.type] {
val mutableTerminatorBehavior = new AbstractBehavior[Stop.type] {
override def onMessage(msg: Stop.type) = msg match {
case Stop Behaviors.stopped
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ object StashSpec {
active(Vector.empty)
}

class MutableStash(ctx: ActorContext[Command]) extends MutableBehavior[Command] {
class MutableStash(ctx: ActorContext[Command]) extends AbstractBehavior[Command] {

private val buffer = StashBuffer.apply[Command](capacity = 10)
private var stashing = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import java.net.URLEncoder
import java.nio.charset.StandardCharsets

import akka.actor.typed._
import akka.actor.typed.scaladsl.{ ActorContext, Behaviors, MutableBehavior }
import akka.actor.typed.scaladsl.{ ActorContext, Behaviors, AbstractBehavior }

import scala.concurrent.duration._
import scala.concurrent.Await
import akka.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit
import org.scalatest.WordSpecLike
//#imports

object MutableIntroSpec {
object OOIntroSpec {

//#chatroom-actor
object ChatRoom {
Expand Down Expand Up @@ -46,7 +46,7 @@ object MutableIntroSpec {
def behavior(): Behavior[RoomCommand] =
Behaviors.setup[RoomCommand](ctx new ChatRoomBehavior(ctx))

class ChatRoomBehavior(ctx: ActorContext[RoomCommand]) extends MutableBehavior[RoomCommand] {
class ChatRoomBehavior(ctx: ActorContext[RoomCommand]) extends AbstractBehavior[RoomCommand] {
private var sessions: List[ActorRef[SessionCommand]] = List.empty

override def onMessage(msg: RoomCommand): Behavior[RoomCommand] = {
Expand Down Expand Up @@ -87,9 +87,9 @@ object MutableIntroSpec {

}

class MutableIntroSpec extends ScalaTestWithActorTestKit with WordSpecLike {
class OOIntroSpec extends ScalaTestWithActorTestKit with WordSpecLike {

import MutableIntroSpec._
import OOIntroSpec._

"A chat room" must {
"chat" in {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@
package akka.actor.typed.javadsl

import akka.actor.typed.{ Behavior, ExtensibleBehavior, Signal }
import akka.actor.typed.javadsl.Behaviors.Receive
import akka.util.OptionVal

/**
* Mutable behavior can be implemented by extending this class and implement the
* abstract method [[MutableBehavior#onMessage]] and optionally override
* [[MutableBehavior#onSignal]].
* An actor `Behavior` can be implemented by extending this class and implement the
* abstract method [[AbstractBehavior#createReceive]]. Mutable state can be defined
* as instance variables of the class.
*
* Instances of this behavior should be created via [[Behaviors#setup]] and if
* This is an Object-oriented style of defining a `Behavior`. A more functional style
* alternative is provided by the factory methods in [[Behaviors]], for example
* [[Behaviors.receiveMessage]].
*
* Instances of this behavior should be created via [[Behaviors.setup]] and if
* the [[ActorContext]] is needed it can be passed as a constructor parameter
* from the factory function.
*
* @see [[Behaviors#setup]]
* @see [[Behaviors.setup]]
*/
abstract class MutableBehavior[T] extends ExtensibleBehavior[T] {
abstract class AbstractBehavior[T] extends ExtensibleBehavior[T] {
private var _receive: OptionVal[Receive[T]] = OptionVal.None
private def receive: Receive[T] = _receive match {
case OptionVal.None
Expand All @@ -37,7 +40,15 @@ abstract class MutableBehavior[T] extends ExtensibleBehavior[T] {
override final def receiveSignal(ctx: akka.actor.typed.ActorContext[T], msg: Signal): Behavior[T] =
receive.receiveSignal(ctx, msg)

/**
* Implement this to define how messages and signals are processed. Use the
* [[AbstractBehavior.receiveBuilder]] to define the message dispatch.
*/
def createReceive: Receive[T]

/**
* Create a [[ReceiveBuilder]] to define the message dispatch of the `Behavior`.
* Typically used from [[AbstractBehavior.createReceive]].
*/
def receiveBuilder: ReceiveBuilder[T] = ReceiveBuilder.create
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ trait ActorContext[T] extends akka.actor.typed.ActorContext[T] {
*
* A message adapter (and the returned `ActorRef`) has the same lifecycle as
* this actor. It's recommended to register the adapters in a top level
* `Behaviors.setup` or constructor of `MutableBehavior` but it's possible to
* `Behaviors.setup` or constructor of `AbstractBehavior` but it's possible to
* register them later also if needed. Message adapters don't have to be stopped since
* they consume no resources other than an entry in an internal `Map` and the number
* of adapters are bounded since it's only possible to have one per message class.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ package akka.actor.typed.javadsl
import java.util.Collections
import java.util.function.{ Function JFunction }

import akka.actor.typed.{ ActorRef, Behavior, BehaviorInterceptor, ExtensibleBehavior, Signal, SupervisorStrategy }
import akka.actor.typed.{ ActorRef, Behavior, BehaviorInterceptor, Signal, SupervisorStrategy }
import akka.actor.typed.internal.{ BehaviorImpl, Supervisor, TimerSchedulerImpl, WithMdcBehaviorInterceptor }
import akka.actor.typed.scaladsl
import akka.annotation.{ ApiMayChange, DoNotInherit }
import akka.annotation.ApiMayChange
import akka.japi.function.{ Function2 JapiFunction2 }
import akka.japi.pf.PFBuilder

Expand Down Expand Up @@ -97,11 +97,10 @@ object Behaviors {
* [[ActorContext]] that allows access to the system, spawning and watching
* other actors, etc.
*
* This constructor is called immutable because the behavior instance doesn't
* have or close over any mutable state. Processing the next message
* results in a new behavior that can potentially be different from this one.
* State is updated by returning a new behavior that holds the new immutable
* state.
* Compared to using [[AbstractBehavior]] this factory is a more functional style
* of defining the `Behavior`. Processing the next message results in a new behavior
* that can potentially be different from this one. State is maintained by returning
* a new behavior that holds the new immutable state.
*/
def receive[T](onMessage: JapiFunction2[ActorContext[T], T, Behavior[T]]): Behavior[T] =
new BehaviorImpl.ReceiveBehavior((ctx, msg) onMessage.apply(ctx.asJava, msg))
Expand All @@ -117,11 +116,10 @@ object Behaviors {
* [[ActorContext]] that allows access to the system, spawning and watching
* other actors, etc.
*
* This constructor is called immutable because the behavior instance doesn't
* have or close over any mutable state. Processing the next message
* results in a new behavior that can potentially be different from this one.
* State is updated by returning a new behavior that holds the new immutable
* state.
* Compared to using [[AbstractBehavior]] this factory is a more functional style
* of defining the `Behavior`. Processing the next message results in a new behavior
* that can potentially be different from this one. State is maintained by returning
* a new behavior that holds the new immutable state.
*/
def receiveMessage[T](onMessage: akka.japi.Function[T, Behavior[T]]): Behavior[T] =
new BehaviorImpl.ReceiveBehavior((_, msg) onMessage.apply(msg))
Expand All @@ -133,11 +131,10 @@ object Behaviors {
* [[ActorContext]] that allows access to the system, spawning and watching
* other actors, etc.
*
* This constructor is called immutable because the behavior instance doesn't
* have or close over any mutable state. Processing the next message
* results in a new behavior that can potentially be different from this one.
* State is updated by returning a new behavior that holds the new immutable
* state.
* Compared to using [[AbstractBehavior]] this factory is a more functional style
* of defining the `Behavior`. Processing the next message results in a new behavior
* that can potentially be different from this one. State is maintained by returning
* a new behavior that holds the new immutable state.
*/
def receive[T](
onMessage: JapiFunction2[ActorContext[T], T, Behavior[T]],
Expand All @@ -151,10 +148,10 @@ object Behaviors {
* Constructs an actor behavior builder that can build a behavior that can react to both
* incoming messages and lifecycle signals.
*
* This constructor is called immutable because the behavior instance does not
* need and in fact should not use (close over) mutable variables, but instead
* return a potentially different behavior encapsulating any state changes.
* If no change is desired, use {@link #same}.
* Compared to using [[AbstractBehavior]] this factory is a more functional style
* of defining the `Behavior`. Processing the next message results in a new behavior
* that can potentially be different from this one. State is maintained by returning
* a new behavior that holds the new immutable state.
*
* @param type the supertype of all messages accepted by this behavior
* @return the behavior builder
Expand Down Expand Up @@ -274,10 +271,6 @@ object Behaviors {
def withTimers[T](factory: akka.japi.function.Function[TimerScheduler[T], Behavior[T]]): Behavior[T] =
TimerSchedulerImpl.withTimers(timers factory.apply(timers))

/** A specialized "receive" behavior that is implemented using message matching builders. */
@DoNotInherit
trait Receive[T] extends ExtensibleBehavior[T]

/**
* Per message MDC (Mapped Diagnostic Context) logging.
*
Expand Down
Loading

0 comments on commit ad3ad15

Please sign in to comment.