Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the AbstractBehavior builder mutable #26309

Merged
Diff settings

Always

Just for now

@@ -4,6 +4,9 @@

package akka.actor.typed.javadsl;

import akka.actor.testkit.typed.javadsl.TestKitJunitResource;
import akka.actor.testkit.typed.javadsl.TestProbe;
import org.junit.ClassRule;
import org.junit.Test;
import org.scalatest.junit.JUnitSuite;

@@ -15,9 +18,13 @@

import static akka.actor.typed.javadsl.Behaviors.same;
import static akka.actor.typed.javadsl.Behaviors.stopped;
import static org.junit.Assert.assertEquals;

/** Test creating [[Behavior]]s using [[BehaviorBuilder]] */
public class BehaviorBuilderTest extends JUnitSuite {

@ClassRule public static final TestKitJunitResource testKit = new TestKitJunitResource();

interface Message {}

static final class One implements Message {
@@ -28,7 +35,6 @@ public String foo() {

static final class MyList<T> extends ArrayList<T> implements Message {};

@Test
public void shouldCompile() {
Behavior<Message> b =
Behaviors.receive(Message.class)
@@ -54,6 +60,86 @@ public void shouldCompile() {
.build();
}

@Test
public void caseSelectedInOrderAdded() {
final TestProbe<Object> probe = testKit.createTestProbe();
Behavior<Object> behavior =
BehaviorBuilder.create()
.onMessage(
String.class,
(context, msg) -> {
probe.ref().tell("handler 1: " + msg);
return Behaviors.same();
})
.onMessage(
String.class,
(context, msg) -> {
probe.ref().tell("handler 2: " + msg);
return Behaviors.same();
})
.build();
ActorRef<Object> ref = testKit.spawn(behavior);
ref.tell("message");
probe.expectMessage("handler 1: message");
}

@Test
public void handleMessageBasedOnEquality() {
final TestProbe<Object> probe = testKit.createTestProbe();
Behavior<Object> behavior =
BehaviorBuilder.create()
.onMessageEquals(
"message",
(context) -> {
probe.ref().tell("got it");
return Behaviors.same();
})
.build();
ActorRef<Object> ref = testKit.spawn(behavior);
ref.tell("message");
probe.expectMessage("got it");
}

@Test
public void applyPredicate() {
final TestProbe<Object> probe = testKit.createTestProbe();
Behavior<Object> behavior =
BehaviorBuilder.create()
.onMessage(
String.class,
(msg) -> "other".equals(msg),
(context, msg) -> {
probe.ref().tell("handler 1: " + msg);
return Behaviors.same();
})
.onMessage(
String.class,
(context, msg) -> {
probe.ref().tell("handler 2: " + msg);
return Behaviors.same();
})
.build();
ActorRef<Object> ref = testKit.spawn(behavior);
ref.tell("message");
probe.expectMessage("handler 2: message");
}

@Test
public void catchAny() {
final TestProbe<Object> probe = testKit.createTestProbe();
Behavior<Object> behavior =
BehaviorBuilder.create()
.onAnyMessage(
(context, msg) -> {
probe.ref().tell(msg);
return same();
})
.build();
ActorRef<Object> ref = testKit.spawn(behavior);
ref.tell("message");
probe.expectMessage("message");
}

interface CounterMessage {};

static final class Increase implements CounterMessage {};
@@ -92,6 +178,12 @@ public Got(int n) {

@Test
public void testImmutableCounter() {
Behavior<CounterMessage> immutable = immutableCounter(0);
ActorRef<CounterMessage> ref = testKit.spawn(immutableCounter(0));
TestProbe<Got> probe = testKit.createTestProbe();
ref.tell(new Get(probe.getRef()));
assertEquals(0, probe.expectMessageClass(Got.class).n);
ref.tell(new Increase());
ref.tell(new Get(probe.getRef()));
assertEquals(1, probe.expectMessageClass(Got.class).n);
}
}
@@ -4,16 +4,23 @@

package akka.actor.typed.javadsl;

import akka.actor.testkit.typed.javadsl.TestKitJunitResource;
import akka.actor.testkit.typed.javadsl.TestProbe;
import akka.actor.typed.ActorRef;
import org.junit.ClassRule;
import org.junit.Test;
import org.scalatest.junit.JUnitSuite;

import akka.actor.typed.Behavior;

import static akka.actor.typed.javadsl.Behaviors.same;
import static org.junit.Assert.assertEquals;

/** Test creating [[MutableActor]]s using [[ReceiveBuilder]] */
public class ReceiveBuilderTest extends JUnitSuite {

@ClassRule public static final TestKitJunitResource testKit = new TestKitJunitResource();

@Test
public void testMutableCounter() {
Behavior<BehaviorBuilderTest.CounterMessage> mutable =
@@ -36,7 +43,7 @@ public void testMutableCounter() {

@Override
public Receive<BehaviorBuilderTest.CounterMessage> createReceive() {
return receiveBuilder()
return newReceiveBuilder()
.onMessage(BehaviorBuilderTest.Increase.class, this::receiveIncrease)
.onMessage(BehaviorBuilderTest.Get.class, this::receiveGet)
.build();
@@ -56,7 +63,7 @@ public MyAbstractBehavior(int initialValue) {
@Override
public Receive<BehaviorBuilderTest.CounterMessage> createReceive() {
assertEquals(42, value);
return receiveBuilder().build();
return newReceiveBuilder().build();
}
}

@@ -65,4 +72,67 @@ public void testInitializationOrder() throws Exception {
MyAbstractBehavior mutable = new MyAbstractBehavior(42);
assertEquals(Behaviors.unhandled(), mutable.receive(null, new BehaviorBuilderTest.Increase()));
}

@Test
public void caseSelectedInOrderAdded() {
final TestProbe<Object> probe = testKit.createTestProbe();
Behavior<Object> behavior =
ReceiveBuilder.<Object>create()
.onMessage(
String.class,
msg -> {
probe.ref().tell("handler 1: " + msg);
return Behaviors.same();
})
.onMessage(
String.class,
msg -> {
probe.ref().tell("handler 2: " + msg);
return Behaviors.same();
})
.build();
ActorRef<Object> ref = testKit.spawn(behavior);
ref.tell("message");
probe.expectMessage("handler 1: message");
}

@Test
public void applyPredicate() {
final TestProbe<Object> probe = testKit.createTestProbe();
Behavior<Object> behavior =
ReceiveBuilder.create()
.onMessage(
String.class,
msg -> "other".equals(msg),
msg -> {
probe.ref().tell("handler 1: " + msg);
return Behaviors.same();
})
.onMessage(
String.class,
msg -> {
probe.ref().tell("handler 2: " + msg);
return Behaviors.same();
})
.build();
ActorRef<Object> ref = testKit.spawn(behavior);
ref.tell("message");
probe.expectMessage("handler 2: message");
}

@Test
public void catchAny() {
final TestProbe<Object> probe = testKit.createTestProbe();
Behavior<Object> behavior =
ReceiveBuilder.create()
.onAnyMessage(
msg -> {
probe.ref().tell(msg);
return same();
})
.build();
ActorRef<Object> ref = testKit.spawn(behavior);
ref.tell("message");
probe.expectMessage("message");
}
}
@@ -207,7 +207,7 @@ else if (rsp instanceof Backend.JobCompleted)

@Override
public Receive<Command> createReceive() {
return receiveBuilder()
return newReceiveBuilder()
.onMessage(
Translate.class,
cmd -> {
@@ -603,7 +603,7 @@ public PrepareToLeaveHome(

@Override
public Receive<Object> createReceive() {
return receiveBuilder()
return newReceiveBuilder()
.onMessage(
Wallet.class,
(wallet) -> {
@@ -5,15 +5,11 @@
package jdocs.akka.typed;

// #imports
import akka.NotUsed;
import akka.actor.typed.ActorRef;
import akka.actor.typed.ActorSystem;
import akka.actor.typed.Behavior;
import akka.actor.typed.Terminated;
import akka.actor.typed.javadsl.AbstractBehavior;
import akka.actor.typed.javadsl.ActorContext;
import akka.actor.typed.javadsl.Behaviors;
import akka.actor.typed.javadsl.Receive;
import akka.actor.typed.javadsl.*;
// #imports
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
@@ -112,29 +108,32 @@ public ChatRoomBehavior(ActorContext<RoomCommand> context) {

@Override
public Receive<RoomCommand> createReceive() {
return receiveBuilder()
.onMessage(
GetSession.class,
getSession -> {
ActorRef<SessionEvent> client = getSession.replyTo;
ActorRef<SessionCommand> ses =
context.spawn(
session(context.getSelf(), getSession.screenName, client),
URLEncoder.encode(getSession.screenName, StandardCharsets.UTF_8.name()));
// narrow to only expose PostMessage
client.tell(new SessionGranted(ses.narrow()));
sessions.add(ses);
return this;
})
.onMessage(
PublishSessionMessage.class,
pub -> {
NotifyClient notification =
new NotifyClient((new MessagePosted(pub.screenName, pub.message)));
sessions.forEach(s -> s.tell(notification));
return this;
})
.build();
ReceiveBuilder<RoomCommand> builder = newReceiveBuilder();

builder.onMessage(
GetSession.class,
getSession -> {
ActorRef<SessionEvent> client = getSession.replyTo;
ActorRef<SessionCommand> ses =
context.spawn(
session(context.getSelf(), getSession.screenName, client),
URLEncoder.encode(getSession.screenName, StandardCharsets.UTF_8.name()));
// narrow to only expose PostMessage
client.tell(new SessionGranted(ses.narrow()));
sessions.add(ses);
return this;
});

builder.onMessage(
PublishSessionMessage.class,
pub -> {
NotifyClient notification =
new NotifyClient((new MessagePosted(pub.screenName, pub.message)));
sessions.forEach(s -> s.tell(notification));
return this;
});

return builder.build();
}
}

@@ -42,13 +42,13 @@ abstract class AbstractBehavior[T] extends ExtensibleBehavior[T] {

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

/**
* Create a [[ReceiveBuilder]] to define the message dispatch of the `Behavior`.
* Create a new [[ReceiveBuilder]] to define the message dispatch of the `Behavior`.
* Typically used from [[AbstractBehavior.createReceive]].
*/
def receiveBuilder: ReceiveBuilder[T] = ReceiveBuilder.create
def newReceiveBuilder: ReceiveBuilder[T] = ReceiveBuilder.create
}
Oops, something went wrong.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.