๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๋นˆ ๊ตฌ๋ฉ ์ฑ„์šฐ๊ธฐ

[Kotlin Coroutines] Job

kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/index.html

 

Job - kotlinx-coroutines-core

Job A background job. Conceptually, a job is a cancellable thing with a life-cycle that culminates in its completion. Jobs can be arranged into parent-child hierarchies where cancellation of a parent leads to immediate cancellation of all its children recu

kotlin.github.io

interface Job : Element

๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…. ๊ฐœ๋…์ ์œผ๋กœ๋Š” ์ž‘์—…์€ ์™„๋ฃŒ๋กœ ๋๋‚˜๋Š” ์ˆ˜๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ์ทจ์†Œํ•  ์ˆ˜ ์žˆ๋‹ค.

์ƒ์œ„-ํ•˜์œ„ ๊ณ„์ธต/๋ถ€๋ชจ-์ž์‹ ๊ณ„์ธต์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์–ด์„œ ๋ถ€๋ชจ๊ฐ€ ์ทจ์†Œ๋˜๋ฉด ๋ชจ๋“  ์ž๋…€๋“ค๋„ ๋ฐ”๋กœ ์žฌ๊ท€์ ์œผ๋กœ ์ทจ์†Œ๋œ๋‹ค.

CancellationExeption ์™ธ์˜ exception์œผ๋กœ ์ž์‹์ด ์ทจ์†Œ๋˜๋ฉด ์ฆ‰์‹œ ๋ถ€๋ชจ์™€ ๋ถ€๋ชจ์˜ ๋ชจ๋“  ๋‹ค๋ฅธ ์ž๋…€๋“ค๋„ ์ทจ์†Œ๋œ๋‹ค. SupervisorJob์œผ๋กœ ์ด ๋™์ž‘์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

๊ธฐ๋ณธ์ ์ธ Job์˜ ์ธ์Šคํ„ด์Šค์˜ ์ƒ์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • launch ์ฝ”๋ฃจํ‹ด ๋นŒ๋”๋กœ Coroutine job์ด ์ƒ์„ฑ๋œ๋‹ค. ํŠน์ • ๋ธ”๋ก ์•ˆ์—์„œ ์‹คํ–‰ํ•˜๊ณ  ๋ธ”๋ก์˜ ์™„๋ฃŒ ๋•Œ ์™„๋ฃŒ๋œ๋‹ค.
  • Job() ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋กœ CompletableJob์ด ์ƒ์„ฑ๋œ๋‹ค. CompletableJob.complete ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ์™„๋ฃŒ๋œ๋‹ค.

๊ฐœ๋…์ ์œผ๋กœ Job์˜ ์‹คํ–‰์€ ๊ฒฐ๊ณผ ๊ฐ’์„ ๋งŒ๋“ค์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค.

 

์ƒํƒœ

Job์€ ์ƒํƒœ(state)๋ฅผ ๊ฐ€์ง„๋‹ค. ์ƒํƒœ๋Š” isActive, isComplete, isCancelled ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

                                          wait children
    +-----+ start  +--------+ complete   +-------------+  finish  +-----------+
    | New | -----> | Active | ---------> | Completing  | -------> | Completed |
    +-----+        +--------+            +-------------+          +-----------+
                     |  cancel / fail       |
                     |     +----------------+
                     |     |
                     V     V
                 +------------+                           finish  +-----------+
                 | Cancelling | --------------------------------> | Cancelled |
                 +------------+                                   +-----------+

 ๋Œ€๊ฒŒ ์ฝ”๋ฃจํ‹ด์€ active ์ƒํƒœ๋กœ ์ƒ์„ฑ๋œ๋‹ค. ์ฝ”๋ฃจํ‹ด ๋นŒ๋”๊ฐ€ CoroutineStart.LAZY ๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„ฃ์œผ๋ฉด new ์ƒํƒœ์˜ ์ฝ”๋ฃจํ‹ด์„ ์ƒ์„ฑํ•ด start() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ job์€ start๋˜๋Š” join์œผ๋กœ active ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.

Job์˜ active ์ƒํƒœ๋Š” 1) ์ฝ”๋ฃจํ‹ด์ด ์ž‘์—…ํ•˜๋Š” ๋™์•ˆ, 2) CompleteableJob์ด ์™„๋ฃŒ(complete)๋˜๊ธฐ ์ „๊นŒ์ง€, ๋˜๋Š” 3) ์ฝ”๋ฃจํ‹ด์ด fail๋˜๊ฑฐ๋‚˜ cancell๋˜๊ธฐ ์ „๊นŒ์ง€์ด๋‹ค.

 

activeํ•œ Job์— exception์ด ์ƒ๊ฒจ ์‹คํŒจํ•˜๋ฉด cancelling ์ƒํƒœ๊ฐ€ ๋œ๋‹ค. Job์€ ์–ธ์ œ๋“  cancel ํ•จ์ˆ˜๋กœ ์ทจ์†Œ ๊ฐ€๋Šฅํ˜€ ์ฆ‰์‹œ cancelling ์ƒํƒœ๋กœ ์ „ํ™˜๋œ๋‹ค. Job์ด ๋ชจ๋“  ์ž‘์—…์„ ๋งˆ์น˜๊ณ  ๋ชจ๋“  ์ž๋…€๋“ค์ด ์™„๋ฃŒ๋˜๋ฉด cancelled ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.

 

activeํ•œ ์ฝ”๋ฃจํ‹ด์˜ body์˜ ์™„๋ฃŒ๋‚˜ CompletableJob.complete๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด Job์€ completing ์ƒํƒœ๊ฐ€ ๋œ๋‹ค. completed ์ƒํƒœ๊ฐ€ ๋˜๊ธฐ ์ „์— ๋ชจ๋“  ์ž๋…€๋“ค์ด ์™„๋ฃŒ๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค. completing ์ƒํƒœ๋Š” Job์˜ ๋‚ด๋ถ€์ ์ธ ์ƒํƒœ๋ผ์„œ ์ž๋…€๋“ค์˜ ์™„๋ฃŒ๋ฅผ ๋‚ด๋ถ€์ ์œผ๋กœ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ์— ๋ฐ”๊นฅ์—์„œ๋Š” active ์ƒํƒœ๋กœ ํ™•์ธ๋œ๋‹ค. 

 

์ทจ์†Œ ์›์ธ

Job์˜ body๊ฐ€ exception์„ ๋ฐœ์ƒ์‹œํ‚ค๋ฉด ์ฝ”๋ฃจํ‹ด Job์€ ์˜ˆ์™ธ์ ์œผ๋กœ ์™„๋ฃŒ๋œ๋‹ค๊ณ  ํ•œ๋‹ค. CompletableJob์€ CompletableJob.completeExeptionally๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์˜ˆ์™ธ์ ์œผ๋กœ ์™„๋ฃŒ๋œ๋‹ค. ์˜ˆ์™ธ์ ์œผ๋กœ ์™„๋ฃŒ๋œ Job์€ ์ทจ์†Œ๋˜๊ณ  ํ•ด๋‹น exception์€ Job์˜ ์ทจ์†Œ ์›์ธ์ด ๋œ๋‹ค.

 

Job์˜ ์ทจ์†Œ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ exception์˜ ์ข…๋ฅ˜์— ๋”ฐ๋ผ์„œ ์‹คํŒจ์™€ ์ •์ƒ์ ์ธ ์ทจ์†Œ๊ฐ€ ๊ตฌ๋ถ„๋œ๋‹ค.

  • CancellationException์ด ์ •์ƒ์ ์œผ๋กœ ์ทจ์†Œ์‹œํ‚ค๊ณ ,
  • ๊ทธ ์™ธ ๋‹ค๋ฅธ exception๋“ค์€ ์‹คํŒจ์‹œํ‚จ๋‹ค. 

Job์ด ์‹คํŒจํ•˜๋ฉด ๊ฐ™์€ exception์œผ๋กœ ๋ถ€๋ชจ๋„ ์ทจ์†Œ๋œ๋‹ค. Job์˜ ์ทจ์†Œ๋Š” ๋ถ€๋ชจ๋ฅผ ์ทจ์†Œ์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค. ๋ถ€๋ชจ๋Š” ์ด๋ ‡๊ฒŒ ์ž๋…€๋“ค์„ ์„(์žฌ๊ท€์ ์œผ๋กœ ๋ชจ๋“  ์ž๋…€๋“ค์„) ์ทจ์†Œ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

 

๋™์‹œ์„ฑ๊ณผ ๋น„๋™๊ธฐ์„ฑ

thread-safeํ•˜๋‹ค

 

ํ•จ์ˆ˜

abstract suspend fun join(): Unit

job์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์ฝ”๋ฃจํ‹ด์„ ์ผ์‹œ์ •์‹œ์‹œํ‚จ๋‹ค. Job์ด ์™„๋ฃŒ๋˜์—ˆ์„ ๋•Œ์™€ ์ฝ”๋ฃจํ‹ด์ด ์•„์ง active ์ƒํƒœ์ผ ๋•Œ join()์„ ํ˜ธ์ถœํ•˜๋ฉด job์ด ์žฌ์‹คํ–‰ํ•œ๋‹ค. job์ด new ์ƒํƒœ์ผ ๋•Œ์—๋Š” ์ฝ”๋ฃจํ‹ด์„ ์‹คํ–‰์‹œํ‚จ๋‹ค.

 

abstract fun cancel(cause: CancellationException? = null) : Unit

job์„ ์ทจ์†Œ์‹œํ‚จ๋‹ค. cause๋Š” ๋””๋ฒ„๊น… ๋ชฉ์ ์œผ๋กœ ์ทจ์†Œ ์ด์œ ๋ฅผ ์ƒ์„ธํ•˜๊ฒŒ ์—๋Ÿฌ๋ฉ”์‹œ์ง€๋กœ ๋‚จ๊ธฐ๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

fun Job.cancel(message: String, casue: Throwable? = null) : Unit

ํ˜„์žฌ Job์„ ์ทจ์†Œ์‹œํ‚จ๋‹ค.

 

fun CoroutineContext.cancel(cause: CancellationException? = null): Unit

์ด context ์•ˆ์˜ Job์„ ์ทจ์†Œ์‹œํ‚จ๋‹ค.

 

suspend fun Job.cancelAndJoin(): Unit

Job์„ ์ทจ์†Œ์‹œํ‚ค๊ณ  ์ทจ์†Œ๋œ Job์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์‹คํ–‰ํ•˜๋Š” ์ฝ”๋ฃจํ‹ด์„ ์ผ์‹œ์ค‘์ง€์‹œํ‚จ๋‹ค.