基本上我想要一个使用Timers和Stash功能的Actor。
在Scala,我们可以做以下 - extends AbstractActor with Timer with Stash
在Java中,我发现了两个类 - AbstractActorWithTimers
和AbstractActorWithStash
。
不幸的是,我无法扩展Java中的两个类。
任何推荐的方式在Java中这样做?
即使我遇到了同样的问题。我想创建一个状态机,我需要stash和timer。
所以在这种情况下,我有两种选择: -
import akka.actor.testkit.typed.javadsl.TestKitJunitResource;
import akka.actor.typed.ActorRef;
import akka.actor.typed.Behavior;
import akka.actor.typed.javadsl.Behaviors;
import akka.actor.typed.javadsl.StashBuffer;
import akka.actor.typed.javadsl.TimerScheduler;
import org.junit.ClassRule;
import org.junit.Test;
import org.scalatest.junit.JUnitSuite;
import java.time.Duration;
public class CountingActor extends JUnitSuite {
public static final class DeviceMessage implements Msg{
private int id;
public DeviceMessage(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
interface Msg{}
private static final class TimeOut implements Msg{}
private static final Object TIMER_KEY = new Object();
private static final StashBuffer<Msg> buffer = StashBuffer.create(10000);
public static Behavior<Msg> behavior(Duration after) {
return Behaviors.withTimers(timers -> active(timers, after));
}
private static Behavior<Msg> idle(TimerScheduler<Msg> timers,
Duration after) {
return Behaviors.receive(Msg.class)
.onMessage(DeviceMessage.class, (ctx, msg) -> {
System.out.println("in idle state got message:"+msg.getId());
buffer.stash(msg);
return Behaviors.same();
})
.onMessage(TimeOut.class,(ctx,msg)->{
System.out.println("in idle state got TimeOut");
timers.cancel(TIMER_KEY);
return buffer.unstashAll(ctx,active(timers,after));
})
.build();
}
private static Behavior<Msg> active(TimerScheduler<Msg> timers,
Duration after) {
return Behaviors.receive(Msg.class)
.onMessage(DeviceMessage.class, (ctx, msg) -> {
System.out.println("got message:"+msg.getId());
timers.startSingleTimer(TIMER_KEY, new TimeOut(), after);
System.out.println(" going to idle state " );
return idle(timers,after);
})
.build();
}
@ClassRule
public static final TestKitJunitResource testKit = new TestKitJunitResource();
@Test
public void stashingExample() throws Exception {
ActorRef<Msg> ref= testKit.spawn(CountingActor.behavior(Duration.ofSeconds(2)));
for(int i=0;;i++){
ref.tell(new DeviceMessage(i));
}
}
}