How can I have an Akka actor executed every 5 min?

前端 未结 4 1783
离开以前
离开以前 2020-12-23 11:01

I\'d like to know if there are any mechanism in Akka that can have an actor executed periodically?

相关标签:
4条回答
  • 2020-12-23 11:33

    You don't really need an actor to do this in Akka 1.3.1 you can schedule a function to be called every 5 minutes like this:

    Scheduler.schedule(() => println("Do something"), 0L, 5L, TimeUnit.MINUTES)
    

    However, if you do want it to be an actor for other reasons you would call it like this

    case class Message()
    
    val actor = actorOf(new Actor {
      def receive = {
        case Message() => println("Do something in actor")
      }
    }).start()
    
    Scheduler.schedule(actor, Message(), 0L, 5L, TimeUnit.MINUTES)
    

    If you're using Akka 2.0 then it would be done like this

    val system = ActorSystem("MySystem")
    system.scheduler.schedule(0 seconds, 5 minutes)(println("do something"))
    

    Or send a message to an actor every 5 minutes like this

    case class Message()
    class MyActor extends Actor {
      def receive = { case Message() => println("Do something in actor") }
    }
    
    val system = ActorSystem("MySystem")
    val actor = system.actorOf(Props(new MyActor), name = "actor")
    system.scheduler.schedule(0 seconds, 5 minutes, actor, Message())
    
    0 讨论(0)
  • 2020-12-23 11:37

    More complete Java example:

    import akka.actor.AbstractActor;
    import akka.actor.ActorRef;
    import scala.concurrent.duration.FiniteDuration;
    import java.util.concurrent.TimeUnit;
    
    public class AnActor extends AbstractActor {
        private final FiniteDuration SCHEDULED_WORK_DELAY = new FiniteDuration(5, TimeUnit.MINUTES);
    
        @Override
        public void preStart() {
            getSelf().tell("Do Scheduled Work", ActorRef.noSender());
        }
    
        @Override
        public Receive createReceive() {
            return receiveBuilder()
            .matchEquals("Do Scheduled Work", work -> {
                doScheduledWork();
             context().system().scheduler().scheduleOnce(SCHEDULED_WORK_DELAY, getSelf(),
                    "Do Scheduled Work", context().dispatcher(), ActorRef.noSender());
            })
            .build();
        }
    
        private void doScheduledWork() { ... }
    }
    
    0 讨论(0)
  • 2020-12-23 11:44

    If anyone want java code then they can do like this

        Cancellable cancellable = system.scheduler().schedule(Duration.Zero(), Duration.create(5, TimeUnit.MINUTES), cronActor, "tick", system.dispatcher(), null);
    
    0 讨论(0)
  • 2020-12-23 11:53

    The approach using schedule is one good approach, although there is a potential for the messages to queue up if the work done on schedule is so great that it might take longer than the scheduled interval. If you want the interval to occur between the end of one iteration and the beginning of the next, then use scheduleOnce with the following pattern:

    import akka.actor.Actor
    import scala.concurrent.duration._
    
    class SchedulingActor extends Actor {
    
      override def preStart(): Unit = {
        self ! "Do Some Work"
      }
    
      def receive = {
        case "Do Some Work" => 
          doWork
          context.system.scheduler.scheduleOnce(5 minutes, self, "Do Some Work")
      }
    
      def doWork = ???
    }
    
    0 讨论(0)
提交回复
热议问题