HTTP 요청 라이프사이클
필수 의존성: io.ktor:ktor-server-core
코드 예제: server-http-request-lifecycle
지원되는 엔진: Netty, CIO
기본적으로 Ktor는 클라이언트의 연결이 끊어지더라도 요청 처리를 계속합니다. HttpRequestLifecycle 플러그인을 사용하면 클라이언트의 연결이 끊어지는 즉시 요청 처리를 취소할 수 있습니다.
이는 클라이언트가 더 이상 응답을 기다리지 않을 때 실행을 중단해야 하는, 실행 시간이 길거나 리소스를 많이 사용하는 요청에 유용합니다.
HttpRequestLifecycle 설치 및 구성
HttpRequestLifecycle 플러그인을 활성화하려면, install 함수를 사용하여 애플리케이션 모듈에 설치하고 cancelCallOnClose 속성을 설정하십시오.
import io.ktor.server.application.*
import io.ktor.server.http.HttpRequestLifecycle
fun Application.module() {
install(HttpRequestLifecycle) {
cancelCallOnClose = true
}
}cancelCallOnClose 속성이 활성화되면, HttpRequestLifecycle 플러그인은 요청마다 취소 핸들러를 설치합니다. 클라이언트의 연결이 끊어지면 해당 특정 라우트를 처리하는 코루틴만 취소됩니다.
취소는 구조화된 동시성(structured concurrency)을 통해 전파되므로, 요청 코루틴에서 시작된 모든 자식 코루틴(예: launch 또는 async 사용)도 취소됩니다. 다음 일시 중단 지점(suspension point)에서 CancellationException이 발생합니다.
취소 처리
리소스 해제나 백그라운드 작업 중단과 같은 정리 작업(cleanup operations)을 수행하기 위해 CancellationException을 캐치할 수 있습니다.
fun Application.module() {
install(HttpRequestLifecycle) {
cancelCallOnClose = true
}
routing {
get("/long-process") {
try {
while (isActive) {
delay(10_000)
log.info("Very important work.")
}
call.respond("Completed")
} catch (e: CancellationException) {
log.info("Cleaning up resources.")
}
}
}
}코루틴 취소는 협력적(cooperative)입니다. 블로킹 코드나 CPU 집약적(CPU-bound)인 코드는 자동으로 중단되지 않습니다. 요청 처리가 오래 걸리는 작업을 수행하는 경우, 취소에 반응하도록
call.coroutineContext.ensureActive()를 호출하십시오.자세한 내용은 코루틴 취소(Coroutine cancellation)를 참조하십시오.
전체 예제는 server-http-request-lifecycle에서 확인할 수 있습니다.
제한 사항
이 플러그인은 CIO 및 Netty 엔진에서만 전적으로 지원됩니다. 서블릿 기반 엔진(또는 기타 지원되지 않는 엔진)은 클라이언트 연결 끊김을 안정적으로 감지할 수 없습니다. 취소는 서버가 응답을 쓰려고 시도할 때만 감지될 수 있습니다.
