2016-07-07 4 views
1

많은 웹 요청 (~ 300000)을하는 스크립트가 있습니다. 이 문제는 각 기능은 비동기 적으로 파일 기술자를 사용하는 각각의 요청, 수천하고 있기 때문에 나는 Too many open files 예외로 실행하는 것입니다이play.api.libs.ws로 요청 일괄 처리

// Setup a new wsClient 
val config = new NingAsyncHttpClientConfigBuilder(DefaultWSClientConfig()).build 
val builder = new AsyncHttpClientConfig.Builder(config) 
val wsClient = new NingWSClient(builder.build) 

// Each of these use the wsClient 
def getAs: Future[Seq[A]] = { ... } 
def getBs: Future[Seq[B]] = { ... } 
def getCs: Future[Seq[C]] = { ... } 
def getDs: Future[Seq[D]] = { ... } 

(for { 
    as <- getAs 
    bs <- getBs 
    cs <- getCs 
    ds <- getDs 
} yield (as, bs, cs, ds)).map(tuple => println("done")) 

같이 보입니다.

나는 각자가 자신의 클라이언트를 배치 할 것이다 그래야 내 기능을 다시 정리 시도 :

def getAs: Future[Seq[A]] = { 
    someCollection.group(1000).map(batch => { 
     val client = new NingWSClient(builder.build) // Make a new client for every batch 
     Future.sequence(batch.map(thing => { 
      wsClient.url(...).map(...) 
     })).map(things => { 
      wsClient.close // Close the client 
      things 
     }) 
    }) 
} 

그러나이 조기 종료하려면를위한 이해의 원인 (오류 메시지 또는 예외없이) :

(for { 
    as <- getAs 
    bs <- getBs // This doesn't happen 
    cs <- getCs // Or any of the following ones 
    ds <- getDs 
} yield (as, bs, cs, ds)).map(tuple => println("done")) 

난 그냥 너무 많은 파일 디스크립터를 열지 않고도 HTTP 요청의 큰 숫자를 만들 수있는 올바른 방법을 찾고 있어요.

답변

2

하나의 웹 서비스 (~ 500 +)에 대한 요청이 너무 많습니다. 그룹화 된 코드 예제가 거의 정확하지만 Iterator[Future[List[Int]]] 또는 Future.sequence -d 인 경우 Future[Iterator[List[Int]]]이 표시됩니다. 그러나 나는 그들이 모두이 비동기 적으로 실행될 것이라고 생각합니다. 첫 번째 일괄 처리를 실행 한 다음 flatMap (완료 될 때까지 기다려야 함)을 실행하고 다음 일괄 처리를 실행해야합니다. 이 this answer 다음, 내가 쓰고 관리 한 것입니다 :이 도움이

val futureIterator = list.grouped(50).foldLeft(Future.successful[List[Int]](Nil)) { 
    (fItems, items) => 
    fItems flatMap { processed => 
     println("PROCESSED: " + processed); println("SPAWNED: " + items); 
     Future.traverse(items)(getFuture) map (res => processed ::: res) 
    } 
} 
println(Await.result(futureIterator, Duration.Inf)) 

희망!

0

당신은 Octoparts 사용할 수 있습니다

https://m3dev.github.io/octoparts/

있지만 wsClient가 외부에 전화를하고있다 있도록 패턴을 되돌리고 싶은처럼 정말 소리, 그리고 당신은 flatmap 미래는 [WSResponse] 돌아 오는 아웃. 그러면 AsyncHttpClient에서 사용하는 내부 Netty 스레드 풀로 미래의 수를 줄이고 설정을 변경하여 Netty 채널 풀의 스레드 수를 늘리거나 줄일 수 있습니다.