2017-11-30 10 views
2

나머지 API는 akka-http으로 제공됩니다. 경우에 따라 외부 데이터베이스 (Apache HBase)에서 데이터를 가져와야하고 데이터베이스가 데이터를 전달하는 데 너무 오래 걸리면 쿼리가 실패하게됩니다.스칼라 - Await.result를 사용하여 선물을 막지 않고 타이머를 사용하는 방법

순진한 방법 중 하나는 Future 안에있는 전화를 랩핑 한 다음 필요한 기간이있는 Await.result으로 차단하는 것입니다.

import scala.concurrent.duration._ 
import scala.concurrent.{Await, Future} 

object AsyncTest1 extends App { 

    val future = Future { 
    getMyDataFromDB() 
    } 

    val myData = Await.result(future, 100.millis) 
} 

이 구현에는 두 개의 스레드가 필요하기 때문에 비효율적 인 것처럼 보입니다. 이렇게하는 효율적인 방법이 있습니까?

여러 개의 쿼리를 병렬로 보내고 동일한 지연 제한을 사용하여 결과를 집계하려는 또 다른 사용 사례가 있습니다.

val future1 = Future { 
    getMyDataFromDB1() 
    } 

    val future2 = Future { 
    getMyDataFromDB2() 
    } 

    val foldedFuture = Future.fold(
    Seq(future1, future2))(MyAggregatedData)(myAggregateFunction) 
) 

    val myData = Await.result(foldedFuture, 100.millis) 

여기에서 같은 질문을 구현하는 가장 효율적인 방법은 무엇입니까?

덕분에 당신의 도움을

답변

1

하나 개의 솔루션은 미래가 당신이 원하는 무엇이든 예외 또는 발생 후 기간을 통과하게됩니다 Akka의 after 기능을 사용하는 것입니다.

보십시오 here. 이 방법을 구현하는 방법을 보여줍니다.

편집 : 나는 경우 링크가 미래에 상처 입는 여기에 코드를 게시 할 것 같아요 도와

import scala.concurrent._ 
import scala.concurrent.duration._ 
import ExecutionContext.Implicits.global 
import scala.util.{Failure, Success} 
import akka.actor.ActorSystem 
import akka.pattern.after 

val system = ActorSystem("theSystem") 

lazy val f = future { Thread.sleep(2000); true } 
lazy val t = after(duration = 1 second, using = system.scheduler)(Future.failed(new TimeoutException("Future timed out!"))) 

val fWithTimeout = Future firstCompletedOf Seq(f, t) 

fWithTimeout.onComplete { 
    case Success(x) => println(x) 
    case Failure(error) => println(error) 
} 
+0

감사합니다. 이 방법이'Await.result' 것보다 더 효율적입니까? 네, 그 이유를 설명해 주시겠습니까? 도움 주셔서 감사합니다. – ogen

+0

예, 스레드를 차단하지 않으므로 'Await.result'보다 더 효율적입니다. DB 호출이 잠시 후에 실패하면 예외를 얻으려고하므로 위의 예에서 미래가 1 초 이내에 완료되고 결과 또는 예외가 발생합니다. –