2017-12-04 23 views
1

현재 블록을 실행해야하거나 (특정 시간 초과에 도달하면) 예외를 throw하는 테스트 함수를 작성하고 있습니다. 이에 그 문제를 해결하기 위해 의도 된 방법 인 경우제한 시간이있는 Kotlin Coroutines

fun <T> runBlockWithTimeout(maxTimeout: Long, block:() -> T): T { 
    val future = CompletableFuture<T>() 

    // runs the coroutine 
    launch { block() } 

    return future.get(maxTimeout, TimeUnit.MILLISECONDS) 
} 

이 작동하지만, 잘 모르겠어요 :

나는 코 틀린에 Coroutines에 이것을 시도하지만 CoroutinesCompletableFuture의 혼합물과 함께 끝났다 코 틀린.

runBlocking { 
    withTimeout(maxTimeout) { 
     block() 
    } 
} 

그러나 이것은 예를 들어, block 호출하는 즉시 작동하지 않을 것 같다 :

나는 다른 방법을 시도 Thread.sleep(...)

그래서 CompletableFuture 접근 방법이 더 좋은가요?

갱신 내가 달성하고자하는 어떤 일 :

비동기 통합 테스트 코드 (RabbitMq에서 데이터를 수신 등)과 같이 어떻게 든 테스트해야 :

var rabbitResults: List = ... // are filled async via RabbitListeners 
... 
waitMax(1000).toSucceed { 
    assertThat(rabbitResults).hasSize(1) 
} 
waitMax(1000).toSucceed { 
    assertThat(nextQueue).hasSize(3) 
} 
... 
+0

일부 테스트 라이브러리를 사용하는 경우 이미 시간 초과 기능이있을 수 있습니다. 예를 들어 JUnit을 사용하면 테스트 메소드에 @Test (timeout = 5000) 주석을 설정할 수 있습니다. –

+0

내가 원하는 것을 더 잘 이해할 수 있도록 설명을 업데이트했습니다. – guenhter

답변

3

withTimeout { ... }로 설계 해당 작업이 취소 가능 인 경우에만 시간 제한에 따라 진행중인 작업을 취소하십시오.

future.get(timeout, unit)과 함께 작동하는 이유는 만 대기 시간이이기 때문입니다. 시간 초과가 경과 한 후에도 계속 실행되는 백그라운드 작업이 어떤 방식 으로든 실제로 취소되거나 중단되지는 않습니다. 당신이 코 루틴과 비슷한 동작을 해내하려면

, 당신은 이 같은 제한 시간, 기다려야한다 : await 당신이 its API documentation를 읽어 확인할 수 있습니다 취소 해 기능이기 때문에 제대로 작동

val d = async { block() } // run the block code in background 
withTimeout(timeout, unit) { d.await() } // wait with timeout 

.

그러나 실제로 시간 초과시 진행중인 작업을 취소하려면 비동기식 및 취소 가능 방식으로 코드를 구현해야합니다. 취소는 협조이므로 시작하려면 코드에서 사용중인 기본 라이브러리가 진행중인 작업 취소를 지원하는 비동기 API를 제공해야합니다.

취소 및 시간 초과에 대한 자세한 내용은 coroutines guide의 해당 섹션에서 읽을 수 있으며 코 루틴을 비동기 라이브러리와 통합하는 방법에 대한 KotlinConf의 Deep Dive into Coroutines을 참조하십시오.