Akka Java API - Как расширить AbstractActor и использовать функции Timers и Stash - PullRequest
0 голосов
/ 03 марта 2019

В основном мне нужен актер, который использует функции Таймеры и Шкат .

В Scala мы можем выполнить следующее - extends AbstractActor with Timer with Stash

В Java я нашел два класса - AbstractActorWithTimers и AbstractActorWithStash.

К сожалению, я не могу расширить оба класса в Java.

Любой рекомендуемый способ сделать это в Java ??

1 Ответ

0 голосов
/ 23 апреля 2019

Даже я застрял в той же проблеме.Я хотел создать конечный автомат, и мне потребовались и тайник, и таймер для одного и того же.

Так что в этом случае у меня остались две опции: -

  • Использовать AbstractFSMWithStash:- Это я не предпочел, так как не был уверен, что в моем решении это скабель

  • Используйте Typed Actors, где вы можете составить таймер и тайник, см. Код ниже сконтрольный пример: -

    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));
            }
    
    
       }
    
    }
    
...