Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I want to start two workers on a Future method called extraire_phrases . I call them in my main, but it seems that the Promise is never fulfilled and I don't get anything at the end of my main, as if the workers don't start. Any ideas? Thanks a lot.

object Main {

    val chemin_corpus:String = "src/corpus.txt"
    val chemin_corpus_backup:String = "src/tartarinalpes.txt"
    val chemin_dictionnaire:String = "src/dicorimes.dmp"
    val chemin_dictionnaire_backup:String = "src/dicorimes2.dmp"

    def main(args:Array[String]){

        val quatrain = Promise[List[Phrase]]()

        var grosPoeme = List[Phrase]()

        Future {
          val texte_1 = Phrases.extraire_phrases(chemin_corpus, chemin_dictionnaire)
          val texte_2 = Phrases.extraire_phrases(chemin_corpus_backup, chemin_dictionnaire_backup)

          texte_1.onComplete {
            case Success(list) => {
              val poeme = new DeuxVers(list)
              poeme.ecrire :: grosPoeme
            }
            case Failure(ex) => {
              quatrain.failure(LameExcuse("Error: " + ex.getMessage))
            }
          }

          texte_2.onComplete {
            case Success(lst) => {
              val poeme2 = new DeuxVers(lst)
              poeme2.ecrire :: grosPoeme
            }
            case Failure(ex) => {
              quatrain.failure(LameExcuse("Error: " + ex.getMessage))
            }
          }
        quatrain.success(grosPoeme)
        }

        println(quatrain.future)
        println(grosPoeme)
    }

}

Here is what I have in my console after execution:

Future(<not completed>)
List()

Even if I remove the Future { before val texte_1 it seems that none of them fire properly, texte_1 starts somehow, sometimes it works, sometimes not, and texte_2 never starts (never goes to completion). No failure either.

// Edit: Alvaro Carrasco's answer is the correct one. Thank both of you however for the help

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
193 views
Welcome To Ask or Share your Answers For Others

1 Answer

Futures are executed asynchronously and your code won't "wait" for them to finish. onComplete will schedule some code to run when the future completes, but it won't force your program to wait for the result.

You need to thread the inner futures using map/flatMap/sequence so you end up with a single future at the end and then wait for it using Await.result(...).

You don't really need Promise here, as exceptions will caught by the future.

Something like this:

object Main {

  val chemin_corpus:String = "src/corpus.txt"
  ...

  def main(args:Array[String]){
    ...

    val f1 = texte_1
      .map {list => 
        val poeme = new DeuxVers(list)
        poeme.ecrire :: grosPoeme
      }

    val f2 = texte_2
      .map {lst => 
        val poeme2 = new DeuxVers(lst)
        poeme2.ecrire :: grosPoeme
      }

    // combine both futures
    val all = for {
      res1 <- f1
      res2 <- f2
    } yield {
      println(...)
    }
    // wait for the combined future
    Await.result(all, 1.hour)
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...