66 votes

Scala Futures - délai d'attente intégré ?

Il y a un aspect des futures que je ne comprends pas exactement à partir du tutoriel officiel réf. http://docs.scala-lang.org/overviews/core/futures.html

Les contrats à terme en Scala ont-ils un mécanisme de temporisation intégré ? Disons que l'exemple ci-dessous était un fichier texte de 5 gigaoctets... est-ce que la portée implicite de "Implicits.global" fait que onFailure se déclenche de manière non bloquante ou est-ce que cela peut être défini ? Et sans une sorte de délai d'attente par défaut, cela ne signifierait-il pas qu'il est possible que ni le succès ni l'échec ne se déclenchent jamais ?

import scala.concurrent._
import ExecutionContext.Implicits.global

val firstOccurence: Future[Int] = future {
  val source = scala.io.Source.fromFile("myText.txt")
  source.toSeq.indexOfSlice("myKeyword")
}
firstOccurence onSuccess {
  case idx => println("The keyword first appears at position: " + idx)
}
firstOccurence onFailure {
  case t => println("Could not process file: " + t.getMessage)
}

0 votes

Voir awaitAll

4 votes

Gardez à l'esprit qu'aucune de ces solutions n'arrêtera réellement l'épidémie. Future de la course. Le seul endroit où vous pouvez arrêter un Future est de l'intérieur.

1 votes

@NikitaVolkov Votre lien ne fonctionne plus. J'ai essayé de trouver le lien correct mais j'ai échoué.

5voto

galbarm Points 647

Si vous voulez que l'auteur (le détenteur de la promesse) soit celui qui contrôle la logique du délai d'attente, utilisez la méthode suivante akka.pattern.after de la manière suivante :

val timeout = akka.pattern.after(10 seconds, system.scheduler)(Future.failed(new TimeoutException(s"timed out during...")))
Future.firstCompletedOf(Seq(promiseRef.future, timeout))

De cette façon, si la logique d'achèvement de votre promesse n'a jamais lieu, le futur de votre appelant sera quand même achevé à un moment donné par un échec.

3voto

akauppi Points 3125

Personne n'a été mentionné akka-streams mais pas encore. Les flux ont une facilité completionTimeout et l'appliquer à un flux à source unique fonctionne comme un futur.

Mais, akka-streams fait également de l'annulation afin de pouvoir mettre fin à l'exécution de la source, c'est-à-dire qu'il signale le délai d'attente à la source.

3voto

gzm0 Points 5799

Vous pouvez spécifier le délai d'attente lorsque vous attendez le futur :

Pour scala.concurrent.Future le result vous permet de spécifier un délai d'attente.

Pour scala.actors.Future , Futures.awaitAll vous permet de spécifier un délai d'attente.

Je ne pense pas qu'il y ait un délai d'attente intégré à l'exécution d'un Future.

3 votes

Cela bloque l'appelant. Le blocage est déconseillé, voir ma réponse pour une solution entièrement non bloquante.

1voto

WeiChing Lin Points 1984

Monix Task a un délai d'attente soutien

import monix.execution.Scheduler.Implicits.global
import monix.eval._
import scala.concurrent.duration._
import scala.concurrent.TimeoutException

val source = Task("Hello!").delayExecution(10.seconds)

// Triggers error if the source does not complete in 3 seconds after runOnComplete
val timedOut = source.timeout(3.seconds)

timedOut.runOnComplete(r => println(r))
//=> Failure(TimeoutException)

1voto

unveloper Points 190

Cette version fonctionne sans utiliser de timer externe (juste Await.result)

import scala.concurrent._
import scala.concurrent.duration.FiniteDuration

object TimeoutFuture {
    def apply[A](
        timeout: FiniteDuration
    )(block: => A)(implicit executor: ExecutionContext): Future[A] =
        try {
            Future { Await.result(Future { block }, timeout) }
        } catch {
            case _: TimeoutException => Future.failed(new TimeoutException(s"Timed out after ${timeout.toString}"))
        }
}

0 votes

Je suis impressionné. Alors que d'autres solutions sont sophistiquées, celle-ci va vraiment à l'essentiel et est assez simple.

1 votes

Comment ça, ça fonctionne sans utiliser le délai d'attente ? Vous utilisez clairement le délai d'attente.

0 votes

Je suis désolé, je n'ai pas été très clair. Je voulais dire sans utiliser de bibliothèque externe pour gérer le timeout comme akka, netty ou tout autre type de timer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X