2017-10-21 3 views
1

Je rencontre un comportement étrange lorsque j'utilise le planificateur d'Akka. Mon code ressemble à peu près comme ceci:Qu'est-ce qui peut faire que le planificateur d'Akka exécute des tâches planifiées avant l'heure planifiée?

val s = ActorSystem("scheduler") 

    import scala.concurrent.ExecutionContext.Implicits.global 

    def doSomething(): Future[Unit] = { 
     val now = new GregorianCalendar(TimeZone.getTimeZone("UTC")) 
     println(s"${now.get(Calendar.MINUTE)}:${now.get(Calendar.SECOND)}:${now.get(Calendar.MILLISECOND)}") 

     // Do many things that include an http request using "dispatch" and manipulation of the response and saving it in a file. 
    } 

    val futures: Seq[Future[Unit]] = for (i <- 1 to 500) yield { 
     println(s"$i : ${i*600}") 
     // AlphaVantage recommends 100 API calls per minute 
     akka.pattern.after(i * 600 milliseconds, s.scheduler) { doSomething() } 
    } 
    Future.sequence(futures).onComplete(_ => s.terminate()) 

Lorsque j'exécute mon code, doSomething est d'abord appelé à plusieurs reprises avec 600 millisecondes entre les appels successifs, comme prévu. Cependant, après un certain temps, tous les appels programmés restants sont soudainement exécutés simultanément.

Je soupçonne que quelque chose à l'intérieur de mon doSomething pourrait interférer avec la planification, mais je ne sais pas quoi. Mon doSomething fait juste une requête http en utilisant dispatch et manipule le résultat, et n'interagit pas directement avec akka ou le planificateur de quelque façon que ce soit. Donc, ma question est:

Qu'est-ce qui peut provoquer l'échec de la planification du planificateur et déclencher soudainement l'exécution immédiate de toutes les tâches planifiées restantes?

(PS: J'ai essayé de simplifier mon doSomething pour poster un exemple minimal chômé , mais mes ont donné lieu à des simplifications de travail exemples.)

Répondre

0

Ok. Je l'ai compris. Dès que l'un des contrats à terme échouent, la ligne

Future.sequence(futures).onComplete(_ => s.terminate()) 

mettra fin au système d'acteur, et toutes les autres tâches planifiées sera appelé.