[2] Kotiln Coroutines - Cancelation / TimeOut
λμμ΄ λ§μ΄ λμλ€.
μ½νλ¦° μ½λ£¨ν΄μ κΈ°μ΄
μ½νλ¦° μ μ½λ£¨ν΄μ λΉλκΈ° νλ‘κ·Έλλ°μ μ²λ¦¬ν μ μλ μ’μ λ°©λ²μ λλ€.
medium.com
Ref.
Youtube : [μμ°¨μ, μ½νλ¦° μ½λ£¨ν΄] https://youtube.com/playlist?list=PLbJr8hAHHCP5N6Lsot8SAnC28SoxwAU5A
Ref : https://kotlinlang.org/
Cancelation
μ€ν νλ μ½λ£¨ν΄μ μ·¨μ νλ λ°©λ² → μ·¨μ νλ κ²μ΄ μ€μν μ΄μ λ νλνλ λ©λͺ¨λ¦¬μ 리μμ€λ₯Ό μ°¨μ§νκ³ μκΈ° λλ¬Έ
μ½λ£¨ν΄ μ·¨μμ 쑰건
1) Cancel νΈμΆ
2) μ½λ£¨ν΄ μμ²΄κ° μ·¨μμ λν΄ νμ‘°μ μΈ μνλ‘ κ΅¬νλμ΄μμ΄μΌν¨.
// λ¨μ μ½λ£¨ν΄ μ·¨μ
// job κ°μ²΄λ μ€νλκ³ μλ μ½λ£¨ν΄μ μ·¨μνκ²λ ν΄μ£Όλ κΈ°λ₯μ κ°μ§κ³ μμ
fun main() = runBlocking{
// μ΄ μ½λ£¨ν΄μ 1000λ²μ λλ©΄μ 0.5μ΄ κ°κ²©μΌλ‘ μ«μλ₯Ό μΆ
val job = launch {
repeat(1000){
println("job: I'm sleeping ${it}...")
delay(500L) //suspend func
}
}
delay(1300L)
println("main : I'm Tired of waiting")
job.cancel() // 1.3μ΄ μ λ μ§λλ©΄ μ΄ APP μ΄ λλ¬μΌλ©΄ μ’κ² μ.
job.join()
println("main : Now i can quit.")
}
/ μ½λ£¨ν΄ μ·¨μμ 쑰건 - supending functions μ μ·¨μ κ°λ₯νλ€.
// suspend ν¨μλ₯Ό νλλΌλ λμ§ μμΌλ©΄ ν΄λΉ μ½λ£¨ν΄μ μ€ν μ·¨μ ν μ μλ€.
fun main() = runBlocking {
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default){
var nextPrintTime = startTime
var i = 0
while(i < 5){
if (System.currentTimeMillis() >= nextPrintTime){
yield() // suspend func : λλ μ΄λ₯Ό μ£Όμ§ μκ³ λ μ’
λ£λ₯Ό μ²΄ν¬ ν μ μμ
// delay(1L) suspend func μ΄ λ°λμ
println("job: I'm sleeping ${i++}...")
nextPrintTime += 500L
}
}
}
delay(1300L)
println("main : I'm tired of waiting")
job.cancelAndJoin() // cancel κ³Ό join μ μμ°¨μ μΌλ‘ λΆλ¬μ£Όλ ν¨μ
// cancel λμ μΌμ μ€λ¨ ν¨μ(yield λ delay)μ μ μΌμ μ€λ¨μ΄ λμλ€κ° μ¬κ° λ λ, exceptionμ λμ§λ€.
println("main : Now i can quit")
}
isActive
// μ½λ£¨ν΄μ΄ μ·¨μ λκΈ° μν΄μ νμ‘°μ μΈ λ°©λ²μ μ·¨νλλ° ν¬κ² 2κ°μ§ λ°©λ²μ΄ μλλ° 2λ²μ§Έ λ°©λ²μ?
// ( 첫λ²μ§Έ λ°©λ²μ μμμ λ΄€λ€ μ£ΌκΈ°μ μΌλ‘ suspending νΈμΆν΄λΌ / λλ²μ§Έ λ°©λ²μ λͺ
μμ μΌλ‘ μνλ₯Ό μ²΄ν¬ νμ¬ _isActive_λ‘)
// isActive : CourouineScopeμ Boolean κ°
// exception μ λμ§μ§λ μλλ€.
fun main() = runBlocking {
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default){
var nextPrintTime = startTime
var i = 0
while(isActive){
if(System.currentTimeMillis() >= nextPrintTime){
println("job : I'm Sleeping ${i++} ..")
nextPrintTime +=500L
}
}
}
delay(1300L)
println("main : Tired waiting")
job.cancelAndJoin()
println("main : Now I can quit")
}
finally
: λ€νΈμν¬λ DB μ°λ€κ° κ°μκΈ° μ½λ£¨ν΄ μΊμ¬ λλ λ±μ μΌμ΄ μμ λ, λ«μμ£Όλ μμΉ
// μ½λ£¨ν΄μ μ’
λ£ν λ, μ΄λ»κ² 리μμ€λ₯Ό ν΄μ νμ¬ μ€ μ μλκ°?
// λ€νΈμν¬λ DBλ₯Ό μ°λ€κ° κ°μκΈ° μ½λ£¨ν΄ cancel λλ©΄ μ΄ νμΌμ λ«μμ£Όκ³ κ°μΌ νλλ°, μ΄ λ«μμ£Όλ μμΉκ° μ΄λμΈκ°? λ«μμ£Όλ 건 finally
fun main() = runBlocking {
val job = launch(Dispatchers.Default){
try{
repeat(1000){
i -> println("job: I'm sleeping ${i} ...")
val curTime = System.currentTimeMillis() // 1970λ
1/1μΌ λΆν° κ²½κ³Όν μκ°μ long κ°μΌλ‘ 리ν΄ν¨
val timeFormat:SimpleDateFormat = SimpleDateFormat("yyyy-mm-dd hh:mm:ss")
val str = timeFormat.format(Date(curTime))
println(str)
println(Date(curTime))
println()
delay(500L) // μ·¨μμ νμ‘°μ μΌλ‘ ꡬνμ΄ λμ΄μμ
}
}finally {
// 리μμ€ ν΄μ μ§μ
println("job: i'm runnig finally")
}
}
delay(1300L)
println("main : Tired waiting")
job.cancelAndJoin() // μΌμ μ€λ¨ λμλ€κ° μ¬κ° λ λ, exceptionμ λμ§ λ finally λΈλ‘μμ 리μμ€ ν΄μ λ₯Ό ν΄λΌ.
println("main : Now I can quit")
}
Timeout
// Timeout
// μ½λ£¨ν΄μ΄ μμλ λ, μ΄ μκ°μ΄ μ§λλ©΄ μ΄ μ½λ£¨ν΄μ μ·¨μ λλ€. 미리 νμ μμμ μ§μ νλ λ°©μ
// withTimeoutμ μ°λ©΄ TimeoutCancellationException μ΄ λλλ°,
// withTimeoutOrNull μ΄λ©΄ Exceptionλ¬μ λ, κ²°κ³Ό κ°μ΄ nullλ‘ λ¨μ΄μ§.
fun main() = runBlocking {
val result = withTimeoutOrNull(2000L){
repeat(1000){
i -> println("i'm sleeping ${i}..")
delay(500L)
}
"Done"
}
println("Result is ${result}")
}