Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Coroutinesから紐解くKtorの仕組み / Revealing Ktor with coroutines

Coroutinesから紐解くKtorの仕組み / Revealing Ktor with coroutines

Kotlin Fest 2019 で行った「Coroutinesから紐解くKtorの仕組み」の資料です。

Yuji Koyano

August 24, 2019
Tweet

More Decks by Yuji Koyano

Other Decks in Programming

Transcript

  1. Coroutines͔Βඥղ͘
    Ktorͷ࢓૊Έ
    Kotlin Fest 2019 

    08/24 (Sat.)


    Recruit Lifestyle. Yuji Koyano

    View Slide

  2. ิ଍
    w ͜ͷεϥΠυதͷ,UPSͷઆ໌͸

    جຊతʹ4FSWFSTJEF,UPSͷΈΛର৅ͱ͍ͯ͠·͢ɻ

    ͱ͸͍͑ɺ$MJFOU4JEF,UPSʹ΋ڞ௨͢Δ಺༰͸ଟ͍Ͱ͢

    w ͜ͷεϥΠυதͷʮίϧʔνϯΛ࡞੒ɾ։࢝͢Δʯ͸

    ޙड़͢ΔTUBSU$PSPVUJOFϝιου΍ͦͷྨࣅͷؔ਺Λ

    ࣮ߦ͢Δɺͱ͍͏ҙຯͰ࢖͍ͬͯ·͢ɻ
    w $PSPVUJOF͸+7.࣮૷Λର৅ͱ͍ͯ͠·͢

    View Slide

  3. ࣗݾ঺հ

    View Slide

  4. @bandwagondagon ykoyano
    Yuji Koyano
    @bandwagondagon ykoyano
    w 3FDSVJU-JGFTUZMFʹͯ

    "OESPJEΤϯδχΞͱͯ͠

    "JSϝΠτͱ͍͏ΞϓϦΛ։ൃத
    w ࠷ۙ͸ɹɹ&OWPZ.PCJMFͰ༡ΜͰ͍·͢

    View Slide

  5. Έͳ͞Μɺ,PUMJO͸ѪͰ͍ͯ·͔͢ʁ

    View Slide

  6. ༷ʑͳѪͰํ
    w "OESPJE
    w J04 ,PUMJO/BUJWF

    w +BWB4DSJQU
    w 4FWFS4JEF,PUMJO

    View Slide

  7. w "OESPJE
    w J04 ,PUMJO/BUJWF

    w +BWB4DSJQU
    w 4FWFS4JEF,PUMJO
    ༷ʑͳѪͰํ

    View Slide

  8. View Slide

  9. Ktorͱ͸ʁ
    w +FU#SBJOTࣾ੡ͷ044
    w 4FSWFSαΠυͱ$MJFOUαΠυͷͭͷϓϩδΣΫτ͕͋Δ

    4FSWFSܰྔͳ8FC"QQMJDBUJPO'SBNFXPSLΛఏڙ

    $MJFOU"TZODISPOPVT)UUQ$MJFOUΛఏڙ
    w ,PUMJOݴޠͷػೳΛϑϧʹ׆༻͍ͯ͠Δͷ͕ಛ௃

    FY$PSPVUJOFT ,PUMJO/BUJWF .VMUJQMBUGPSN

    View Slide

  10. Ktorͱ͸ʁ
    w +FU#SBJOTࣾ੡ͷ044
    w 4FSWFSαΠυͱ$MJFOUαΠυͷͭͷϓϩδΣΫτ͕͋Δ

    4FSWFSܰྔͳ8FC"QQMJDBUJPO'SBNFXPSLΛఏڙ

    $MJFOU"TZODISPOPVT)UUQ$MJFOUΛఏڙ
    w ,PUMJOݴޠͷػೳΛϑϧʹ׆༻͍ͯ͠Δͷ͕ಛ௃

    FY$PSPVUJOFT ,PUMJO/BUJWF .VMUJQMBUGPSN

    View Slide

  11. ͜ͷηογϣϯͷ໨త
    w ,UPSͷઃܭ΍ಛ௃ɺࢥ૝ͳͲΛཧղ͢Δ͜ͱͰ

    4FSWFS4*EF,PUMJOͱͯ͠ͷ,UPSͷਂ͍ཧղΛಘΔ
    w ,UPS͕$PSPVUJOFTΛ࢖ͬͯͲͷΑ͏ʹඇಉظ

    ϓϩάϥϛϯάϞσϧΛ࣮ݱ͍ͯ͠Δͷ͔Λཧղ͢Δ͜ͱͰ

    $PSPVUJOFTͷԠ༻తͳ࢖͍ํΛ஌ͬͯ΋Β͏

    View Slide

  12. ͜ͷηογϣϯͷ໨త
    w ,UPSͷઃܭ΍"1*
    w $PSPVUJOFͷ

    ௿Ϩϕϧͳ"1*ͷ঺հ
    w 4FSWFS4JEF,UPS
    w ࣮ફతͳ,UPSͷ5JQT΍ӡ༻ࣄྫ
    w $PSPVUJOFͷ

    Ұൠతͳ஌ࣝ΍࢖͍ํ
    w $MJFOU4JEF,UPS
    ࿩͢͜ͱ ࿩͞ͳ͍͜ͱ

    View Slide

  13. $PSPVUJOFTͷ௿Ϩϕϧ"1*
    ,UPSͱඇಉظॲཧύΠϓϥΠϯ
    ,UPSΛ$PSPVUJOFTͰඥղ͘
    ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ
    ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

    View Slide

  14. $PSPVUJOFTͷ௿Ϩϕϧ"1*
    ,UPSͱඇಉظॲཧύΠϓϥΠϯ
    ,UPSΛ$PSPVUJOFTͰඥղ͘
    ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ
    ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

    View Slide

  15. w ,UPSͷઃܭࢥ૝ͷҰͭɻ௚༁͢ΔͱʮࣗઆΛ࣋ͨͳ͍ʯ
    w ϑϨʔϜϫʔΫଆ͸ΞϓϦߏ੒΍ػೳΛۃྗڧ੍͠ͳ͍ͨΊ

    ΞϓϦέʔγϣϯ։ൃऀͷҙࢥʹଟ͕͘ҕͶΒΕ͍ͯΔ

    DG/PEFKTͷϑϨʔϜϫʔΫ&YQSFTT
    Unopinionated

    View Slide

  16. w ϑϨʔϜϫʔΫͷҰൠతͳओཁػೳΛίΞίϯϙʔωϯτ͔Β

    ෼཭͢Δ͜ͱͰϚΠΫϩϑϨʔϜϫʔΫΛ࣮ݱ

    DG3VCZPO3BJMTͱ4JOBUSB 4QSJOH'SBNFXPSL
    w σϑΥϧτઃఆͰ͸ϩΪϯάػೳ΍

    ςϯϓϨʔτΤϯδϯ΍+TPO.BQQFSͳͲ΋ಋೖ͞Ε͍ͯͳ͍
    ബ͍ϑϨʔϜϫʔΫ

    View Slide

  17. ϚΠΫϩϑϨʔϜϫʔΫͷϝϦοτ
    w ඞཁ࠷খݶͷߏ੒Ͱ։ൃΛ։࢝Ͱ͖ΔͷͰ

    ϓϩτλΠϐϯάͱͯ͠ͷΞϓϦέʔγϣϯ΍

    ϚΠΫϩαʔϏεతʹ୯Ұͷ੹຿Λ࣋ͭΞϓϦέʔγϣϯΛ

    খ͘͞࡞Γ࢝ΊΔͷʹద͍ͯ͠Δ
    w ҉໧తͳઃఆ΍ػೳ͕΄ͱΜͲͳ͍ͨΊ

    ϑϨʔϜϫʔΫͱ࣮ͯ͠ߦ͞Ε͍ͯΔػೳΛ

    ΞϓϦέʔγϣϯ։ൃऀ͕೺Ѳ͢Δͷ͕ൺֱత༰қ

    View Slide

  18. $PSPVUJOFTͷ௿Ϩϕϧ"1*
    ,UPSͱඇಉظॲཧύΠϓϥΠϯ
    ,UPSΛ$PSPVUJOFTͰඥղ͘
    ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ
    ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

    View Slide

  19. FeatureʹΑΔϓϥάΠϯػߏ
    w ೝূ΍%*ͳͲͷ࣮ફతͳػೳ͔ΒϧʔςΟϯά΍

    ϩΪϯάͳͲͷجຊతͳػೳ·Ͱͷ΄ͱΜͲ͕

    'FBUVSFͱ͍͏ϓϥάΠϯܗࣜͰຊମ͔Β

    ੾Γग़ͯ͠ఏڙ͞Ε͍ͯΔ
    w 'FBUVSFΛΞϓϦέʔγϣϯʹJOTUBMM͢Δ͜ͱͰ

    ࣗ༝ʹػೳΛ௥ՃͰ͖Δ
    w ಠࣗʹ$VTUPN'FBUVSFΛ࣮૷͢Δ͜ͱ΋Մೳ

    View Slide

  20. fun Application.main() {
    routing {
    get("/kotline_fest") {
    call.respondText {
    "Kotlin Fest 2019!”
    }
    }
    }
    }
    Featureͷinstallྫ
    w จࣈྻΛฦ͢࠷খͷΞϓϦέʔγϣϯͷίʔυ

    View Slide

  21. fun Application.main() {
    install(DefaultHeaders)
    install(CallLogging)
    routing {
    get("/kotline_fest") {
    call.respondText {
    "Kotlin Fest 2019!”
    }
    }
    }
    }
    Featureͷinstallྫ
    w JOTUBMMϝιουΛ࢖༻ͯ͠ΞϓϦέʔγϣϯʹػೳ௥Ճ

    View Slide

  22. ύΠϓϥΠϯػߏ
    w ,UPS͕ϦΫΤετΛड͚ͯॲཧΛߦ্͍ͬͯ͘Ͱ

    ΞϓϦέʔγϣϯ։ൃऀ͕ॊೈʹ'FBUVSF΍3PVUJOHຖͷॱংΛ

    ఆٛͰ͖ΔΑ͏ͳܭࢉύΠϓϥΠϯΛఏڙ
    w ܭࢉύΠϓϥΠϯΛ֦ு͢ΔͨΊͷ"1*΋ఏڙ͞Ε͍ͯͯ

    ಠࣗͷܭࢉύΠϓϥΠϯΛ࣮૷ͯ͠

    $VTUPN'FBUVSFͱͯ͠JOTUBMM ࣮ߦ͢Δ͜ͱ΋Մೳ

    View Slide

  23. 1IBTF 1IBTF 1IBTF
    1IBTF
    {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ύΠϓϥΠϯػߏͷΠϝʔδ

    View Slide

  24. {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w ,UPS͸ϦΫΤετΛड͚ΔͱίϧʔνϯΛ։࢝ͯ͠

    ܭࢉύΠϓϥΠϯʹׂΓ౰ͯΒΕͨॲཧΛ࣮ߦ͍ͯ͘͠
    1IBTF 1IBTF 1IBTF
    1IBTF

    View Slide

  25. {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w ,UPS͸ϦΫΤετΛϋϯυϦϯά͢ΔͱίϧʔνϯΛ։࢝ͯ͠
    ܭࢉ1JQFMJOFʹׂΓ౰ͯΒΕͨॲཧΛ࣮ߦ͍ͯ͘͠
    1IBTF 1IBTF 1IBTF
    1IBTF
    override fun handle(ɾɾɾ) {
    try {
    ɾɾɾ
    launch(dispatcher + JettyCallHandlerCoroutineName)
    ɹɹɹɹɹɹɹɾɾɾ
    try {
    pipeline().execute(call)
    } catch (cancelled: CancellationException) {
    ɹɹɹɹɹɹɹɹɹɹɾɾɾ
    }
    }
    } catch (ex: Throwable) {
    ɹɹɹɹɹɹɹɾɾɾ
    }
    }

    View Slide

  26. {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w ,UPS͸ϦΫΤετΛϋϯυϦϯά͢ΔͱίϧʔνϯΛ։࢝ͯ͠
    ܭࢉ1JQFMJOFʹׂΓ౰ͯΒΕͨॲཧΛ࣮ߦ͍ͯ͘͠
    1IBTF 1IBTF 1IBTF
    1IBTF
    override fun handle(ɾɾɾ) {
    try {
    ɾɾɾ
    launch(dispatcher + JettyCallHandlerCoroutineName)
    ɹɹɹɹɹɹɹɾɾɾ
    try {
    pipeline().execute(call)
    } catch (cancelled: CancellationException) {
    ɹɹɹɹɹɹɹɹɹɹɾɾɾ
    }
    }
    } catch (ex: Throwable) {
    ɹɹɹɹɹɹɹɾɾɾ
    }
    }

    View Slide

  27. {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w ܭࢉύΠϓϥΠϯ͸1JQFMJOF1IBTFʹΑͬͯॲཧͷॱংΛఆٛ

    1JQFMJOF1IBTFຖʹ೚ҙͷॲཧΛׂΓ౰͍ͯͯ͘͜ͱʹΑͬͯ

    ύΠϓϥΠϯશମͷॲཧΛܾఆ͢Δ͜ͱ͕Ͱ͖Δ
    1IBTF 1IBTF 1IBTF
    1IBTF

    View Slide

  28. {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 1JQFMJOF1IBTF͸طʹఆٛ͞Ε͍ͯΔ΋ͷ΋͋Ε͹

    ࣗ෼Ͱ৽͘͠೚ҙͷॱ൪Ͱ௥Ճ͢Δ͜ͱ΋Ͱ͖Δ

    ҎԼ͸1JQFMJOF1IBTFͷྫ
    4FUVQ .POJUPSJOH $BMM 4FOE

    View Slide

  29. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    w 1JQFMJOF1IBTF΁ͷॲཧͷׂΓ౰ͯ͸

    'FBUVSFͷJOTUBMM΍3PVUJOHͷఆٛʹΑͬͯߦΘΕΔ
    %FGBVMU)FBEFS $BMM-PHHJOH
    'FBUVSF
    3PVUJOH

    View Slide

  30. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    %FGBVMU)FBEFS $BMM-PHHJOH
    'FBUVSF
    3PVUJOH
    JOTUBMM

    w 1JQFMJOF1IBTF΁ͷॲཧͷׂΓ౰ͯ͸

    'FBUVSFͷJOTUBMM΍3PVUJOHͷఆٛʹΑͬͯߦΘΕΔ

    ˞ͻͱͭͷϑΣΠζʹෳ਺ͷॲཧΛׂΓ౰ͯΔ͜ͱ΋Մೳ

    View Slide

  31. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 1JQFMJOF1IBTF΁ͷॲཧͷׂΓ౰ͯ͸

    'FBUVSFͷJOTUBMM΍3PVUJOHͷఆٛʹΑͬͯߦΘΕΔ

    View Slide

  32. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    "QQMJDBUJPO$BMM
    w 1JQFMJOF1IBTFؒͰ͸"QQMJDBUJPO$BMMͱ͍͏

    ΞϓϦέʔγϣϯ΍ϦΫΤετɾϨεϙϯεʹؔ͢Δ৘ใΛ

    อ࣋ͨ͠NVUBCMFͳΦϒδΣΫτΛڞ༗͍ͯ͠Δ

    View Slide

  33. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }

    View Slide

  34. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 5ISFBEᶃͰϦΫΤετΛϋϯυϦϯάͯ͠

    5ISFBEᶄ্ͰίϧʔνϯΛ։࢝

    ͦͷ··5ISFBEᶄ্ͷίϧʔνϯͰ1JQFMJOFΛ࣮ߦ

    View Slide

  35. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 5ISFBEᶃͷεϨου͸ϊϯϒϩοΩϯάঢ়ଶͳͷͰ

    ଞͷϦΫΤετΛ଴ͭ͜ͱ͕Ͱ͖Δ

    View Slide

  36. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕։࢝
    {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 5ISFBEᶄ্ͷίϧʔνϯ͕ผͷίϧʔνϯΛಉεϨουͰ։࢝
    ᶃ4FUVQϑΣΠζʹׂΓ౰ͯΒΕͨϥϜμࣜΛ࣮ߦ

    View Slide

  37. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕ऴྃ ॲཧ͕։࢝
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    {
    getAuth(userID)
    }
    {
    setHeader()
    }
    w ᶃ4FUVQϑΣΠζΛ࣮ߦ͢Δίϧʔνϯ͕׬ྃ

    ᶄ.POJUPSJOHϑΣΠζͷॲཧΛ࣮ߦ͢ΔผͷίϧʔνϯΛ։࢝

    View Slide

  38. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕։࢝
    {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    w ᶄ.POJUPSJOHϑΣΠζΛ࣮ߦ͢Δίϧʔνϯ͕׬ྃ

    ᶅ$BMMϑΣΠζͰผͷॲཧΛ࣮ߦ͢ΔผͷίϧʔνϯΛ։࢝

    View Slide

  39. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕։࢝
    w ᶅ$BMMϑΣΠζΛ࣮ߦ͢Δίϧʔνϯ͕׬ྃ

    ᶆ4FOEϑΣΠζͰผͷॲཧΛ࣮ߦ͢ΔผͷίϧʔνϯΛ։࢝

    View Slide

  40. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕ऴྃ
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 4FOEϑΣΠζͷॲཧ͕׬ྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ͕
    ऴྃ͠ɺݺͼग़͠ݩͷ5ISFBEᶃͷ໭ͬͯϋϯυϦϯά͕ऴྃ

    View Slide

  41. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 5ISFBEᶄ্Ͱ։࢝ͨ͠࠷ॳͷίϧʔνϯ͕

    ֤1JQFMJOF1IBTFຖʹ౎౓ίϧʔνϯΛੜ੒͍ͯ͠Δ

    ͦΕΒ͸શͯ5ISFBEᶄ্Ͱಈ࡞͢Δ
    ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%

    View Slide

  42. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }

    View Slide

  43. ϓϥάΠϯͱύΠϓϥΠϯػߏ
    w ,UPSຊମ͸࠷௿ݶͷػೳ͔࣋ͨ͠ͳ͍୅ΘΓʹ

    'FBUVSFΛ࢖ͬͨϓϥάΠϯػߏʹΑͬͯ

    Ϣʔβʔ͕ࣗ༝ʹػೳΛ௥Ճ͢Δ͜ͱ͕Ͱ͖Δ
    w ,UPS͔Βఏڙ͞ΕΔܭࢉύΠϓϥΠϯػߏͱ"1*ʹΑͬͯ

    ΞϓϦέʔγϣϯ։ൃऀ͕ݻ༗ͷϧʔςΟϯάॲཧ΍

    ෳ਺ϧʔςΟϯάʹ·͕ͨͬͨڞ௨ॲཧΛॊೈͳॱ൪Ͱ

    ࣮ߦͤ͞Δ͜ͱ͕Մೳ

    View Slide

  44. $PSPVUJOFTͷ௿Ϩϕϧ"1*
    ,UPSͱඇಉظॲཧύΠϓϥΠϯ
    ,UPSΛ$PSPVUJOFTͰඥղ͘
    ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ
    ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

    View Slide

  45. w ίϧʔνϯΛར༻ͯ͠ඇಉظϓϩάϥϛϯάϞσϧΛ

    ѻ͍΍͍͢ܗͰΞϓϦέʔγϣϯ։ൃऀʹఏڙ
    w ύΠϓϥΠϯ಺Ͱࣗ༝ʹඇಉظॲཧΛ։࢝͢Δ͜ͱ͕Ͱ͖Δ
    ඇಉظॲཧύΠϓϥΠϯ

    View Slide

  46. w TVTQFOEؔ਺ʹΑͬͯҰ࣌தஅ͢Δྫ
    w MBVODIؔ਺ͰίϧʔνϯΛผεϨουͰ։࢝͢Δྫ
    w BTZODؔ਺ͰίϧʔνϯΛผεϨουͰ։࢝͢Δྫ
    w QSPDFFEϝιουͱBXBJUؔ਺Λ૊Έ߹ΘͤΔྫ
    ঺հ͢ΔඇಉظॲཧύΠϓϥΠϯͷ࢖͍ํ

    View Slide

  47. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    setHeader()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }

    View Slide

  48. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    delay(1000L)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    {
    getAuth(userID)
    }
    Ұ࣌தஅ͢Δؔ਺
    1 : suspendؔ਺ʹΑͬͯҰ࣌தஅ͢Δྫ

    View Slide

  49. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    delay(1000L)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 5ISFBEᶃͰϦΫΤετΛϋϯυϦϯάͯ͠

    5ISFBEᶄ্ͰίϧʔνϯΛ։࢝

    ͦͷ··5ISFBEᶄ্ͷίϧʔνϯͰ1JQFMJOFΛ࣮ߦ

    View Slide

  50. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ
    ॲཧΛ࣮ߦ
    {
    delay(1000L)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }

    View Slide

  51. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕ऴྃ ॲཧΛ࣮ߦ
    {
    delay(1000L)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    {
    getAuth(userID)
    }
    w 4FUVQϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ

    ίϧʔνϯ͕.POJUPSJOHϑΣΠζͷॲཧΛ࣮ߦ
    Ұ࣌தஅ͢Δؔ਺

    View Slide

  52. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    w ॲཧΛҰ࣌தஅͯ͠ɺॲཧΛ࠶։͢Δ·Ͱίϧʔνϯ্Ͱ଴ػ

    5ISFBEᶄ͸ผͷϦΫΤετͷॲཧΛड͚෇͚ΒΕΔΑ͏ʹͳΔ
    ॲཧΛҰ࣌தஅ
    {
    delay(1000L)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ
    Ұ࣌தஅ͢Δؔ਺

    View Slide

  53. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧΛ࠶։
    {
    delay(1000L)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ
    w தஅॲཧ͕׬ྃͨ͠Β5ISFBEᶄͰ.POJUPSJOHϑΣΠζͷ

    ࢒ΓͷॲཧΛ࣮ߦ ҧ͏5ISFBEͷՄೳੑ͕͋Δ͜ͱʹ஫ҙ

    View Slide

  54. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧΛ࣮ߦ
    {
    delay(1000L)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ
    w .POJUPSJOHϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ

    ίϧʔνϯ͕$BMMϑΣΠζͷॲཧΛ࣮ߦ
    ॲཧ͕ऴྃ

    View Slide

  55. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧΛ࣮ߦ
    {
    delay(1000L)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    w $BMMϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ

    ίϧʔνϯ͕4FOEϑΣΠζͷॲཧΛ࣮ߦ

    View Slide

  56. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕ऴྃ
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    {
    delay(1000L)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 4FOEϑΣΠζͷॲཧ͕׬ྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ͕
    ऴྃ͠ɺݺͼग़͠ݩͷ5ISFBEᶃͷ໭ͬͯϋϯυϦϯά͕ऴྃ

    View Slide

  57. w ॲཧ͕Ұ࣌தஅ͍ͯ͠ΔؒʹύΠϓϥΠϯ࣮ߦεϨουΛ

    ผͷϦΫΤετͷͨΊʹར༻͢Δ͜ͱ͕Ͱ͖Δ
    w ແҋʹεϨουΛੜ੒ͤͣɺޮ཰తʹαʔόʔͷϦιʔεΛ

    ׆༻͢Δ͜ͱ͕Ͱ͖Δ
    1 : suspendؔ਺ʹΑͬͯҰ࣌தஅ͢Δྫ

    View Slide

  58. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    launch {
    delay(1000L)
    }

    logging(request)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    {
    getAuth(userID)
    }
    ผεϨουͰ

    ॲཧΛߦ͏ϥϜμ
    2 : launchؔ਺ͷྫ

    View Slide

  59. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    launch {
    delay(1000L)
    }

    logging(request)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 5ISFBEᶃͰϦΫΤετΛϋϯυϦϯάͯ͠

    5ISFBEᶄ্ͰίϧʔνϯΛ։࢝

    ͦͷ··5ISFBEᶄ্ͷίϧʔνϯͰ1JQFMJOFΛ࣮ߦ

    View Slide

  60. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ
    ॲཧΛ࣮ߦ
    {
    launch {
    delay(1000L)
    }

    logging(request)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }

    View Slide

  61. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕ऴྃ ॲཧΛ࣮ߦ
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    {
    getAuth(userID)
    }
    w 4FUVQϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ

    ίϧʔνϯ͕.POJUPSJOHϑΣΠζͷॲཧΛ࣮ߦ
    {
    launch {
    delay(1000L)
    }

    logging(request)
    }
    ผεϨουͰ

    ॲཧΛߦ͏ϥϜμ

    View Slide

  62. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    w MBVODIؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝

    5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ
    MBVODIؔ਺Λ࣮ߦ
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ
    {
    launch {
    delay(1000L)
    }

    logging(request)
    }
    ผεϨουͰ

    ॲཧΛߦ͏ϥϜμ

    View Slide

  63. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    w MBVODIؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝

    5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ
    {
    launch {
    delay(1000L)
    }

    logging(request)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ ࢒ΓͷॲཧΛ࣮ߦ
    5ISFBEᶅͰ࣮ߦத
    ผεϨουͰ

    ॲཧΛߦ͏ϥϜμ

    View Slide

  64. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧΛ࣮ߦ
    {
    launch {
    delay(1000L)
    }

    logging(request)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ
    w .POJUPSJOHϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ

    ίϧʔνϯ͕$BMMϑΣΠζͷॲཧΛ࣮ߦ
    ॲཧ͕ऴྃ
    5ISFBEᶅͰ࣮ߦத

    View Slide

  65. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧΛ࣮ߦ
    {
    launch {
    delay(1000L)
    }

    logging(request)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    w $BMMϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ

    ίϧʔνϯ͕4FOEϑΣΠζͷॲཧΛ࣮ߦ
    5ISFBEᶅͰ࣮ߦத

    View Slide

  66. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕ऴྃ
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    {
    launch {
    delay(1000L)
    }

    logging(request)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 4FOEϑΣΠζͷॲཧ͕׬ྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ͸
    5ISFBEᶅͷίϧʔνϯ͕ऴྃ͢Δ·Ͱ଴ͭ
    5ISFBEᶅͰ࣮ߦத

    View Slide

  67. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕ऴྃ
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    {
    launch {
    delay(1000L)
    }

    logging(request)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    5ISFBEᶅͰ

    ॲཧ͕ऴྃ
    w 5ISFBEᶅͷίϧʔνϯ͕ऴྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ
    ͕ऴྃ͠ɺݺͼग़͠ݩͷ5ISFBEᶃͷ໭ͬͯϋϯυϦϯά͕ऴྃ

    View Slide

  68. 2 : launchؔ਺ͷྫ
    w MBVODIίϧʔνϯϏϧμʔΛύΠϓϥΠϯ্Ͱ࣮ߦ͢Δͱ

    ผεϨουͰ৽ͨʹίϧʔνϯΛ։࢝ͯ͠

    ݩͷύΠϓϥΠϯͷॲཧͱ͸ฏߦʹܭࢉΛߦ͏͜ͱ͕Ͱ͖Δ
    w ͜ΕʹΑͬͯ*0଴͕ͪ௕͍ॲཧΛMBVODIίϧʔνϯϏϧμʔͰͷ

    ίϧʔνϯͰ࣮ߦ͢Δ͜ͱʹΑͬͯ

    ޮ཰తʹฏߦॲཧΛߦ͏͜ͱ͕Ͱ͖Δ৔߹͕͋Δ

    View Slide

  69. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    async {
    delay(1000L)

    “Finish”
    }.await()
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    {
    getAuth(userID)
    }
    ผεϨουͰॲཧΛߦͬͯ

    ׬ྃΛ଴ͭϥϜμ
    3 : asyncؔ਺ͷྫ

    View Slide

  70. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    async {
    delay(1000L)

    “Finish”
    }.await()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 5ISFBEᶃͰϦΫΤετΛϋϯυϦϯάͯ͠

    5ISFBEᶄ্ͰίϧʔνϯΛ։࢝

    ͦͷ··5ISFBEᶄ্ͷίϧʔνϯͰ1JQFMJOFΛ࣮ߦ

    View Slide

  71. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ
    ॲཧΛ࣮ߦ
    {
    async {
    delay(1000L)

    “Finish”
    }.await()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }

    View Slide

  72. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕ऴྃ ॲཧΛ࣮ߦ
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    {
    getAuth(userID)
    }
    w 4FUVQϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ

    ίϧʔνϯ͕.POJUPSJOHϑΣΠζͷॲཧΛ࣮ߦ
    {
    async {
    delay(1000L)

    “Finish”
    }.await()
    }
    ผεϨουͰॲཧΛߦͬͯ

    ׬ྃΛ଴ͭϥϜμ

    View Slide

  73. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    w BTZODؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝

    5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ
    BTZODؔ਺Λ࣮ߦ
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ
    {
    async {
    delay(1000L)

    “Finish”
    }.await()
    }
    ผεϨουͰॲཧΛߦͬͯ

    ׬ྃΛ଴ͭϥϜμ

    View Slide

  74. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    w BTZODؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝

    5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ
    {
    async {
    delay(1000L)

    “Finish”
    }.await()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ ࢒ΓͷॲཧΛ࣮ߦ
    ผεϨουͰॲཧΛߦͬͯ

    ׬ྃΛ଴ͭϥϜμ
    5ISFBEᶅͰ࣮ߦத

    View Slide

  75. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    async {
    delay(1000L)

    “Finish”
    }.await()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ
    5ISFBEᶅ͕

    ऴΘΔ·Ͱ଴ػ
    5ISFBEᶅͰ࣮ߦத
    ผεϨουͰॲཧΛߦͬͯ

    ׬ྃΛ଴ͭϥϜμ
    w 5ISFBEᶅ্ͷίϧʔνϯͷ׬ྃΛ଴ػ͍ͯ͠ΔͷͰ

    5ISFBEᶄͷ.POJUPSJOHϑΣΠζͷॲཧ΋׬ྃ͠ͳ͍··

    View Slide

  76. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    async {
    delay(1000L)

    “Finish”
    }.await()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ ࢒ΓͷॲཧΛ࣮ߦ
    ผεϨουͰॲཧΛߦͬͯ

    ׬ྃΛ଴ͭϥϜμ
    w 5ISFBEᶅ্ͷίϧʔνϯͷ׬ྃͷ݁ՌΛड͚ͯ

    5ISFBEᶄͷ.POJUPSJOHϑΣΠζͷॲཧΛ࠶։
    5ISFBEᶅͰॲཧ͕ऴྃ

    View Slide

  77. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧΛ࣮ߦ
    {
    async {
    delay(1000L)

    “Finish”
    }.await()
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    w 5ISFBEᶄͷ.POJUPSJOHϑΣΠζͷॲཧ͕ऴྃͯ͠

    ΍ͬͱ$BMMϑΣΠζͷ࣮ߦΛ։࢝Ͱ͖Δ
    5ISFBEᶅͰॲཧ͕ऴྃ

    View Slide

  78. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧΛ࣮ߦ
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    w 5ISFBEᶄͷ.POJUPSJOHϑΣΠζͷॲཧ͕ऴྃͯ͠

    ΍ͬͱ$BMMϑΣΠζͷ࣮ߦΛ։࢝Ͱ͖Δ
    ͜ͷผεϨουͷॲཧ଴ͪͷ࣌ؒΛ

    ༗ޮʹ࢖͏ͨΊͷ"1*͕

    ,UPS͔Βఏڙ͞Ε͍ͯ·͢ʂ

    View Slide

  79. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    {
    getAuth(userID)
    }
    QSPDFFE
    Λ࣮ߦ͢ΔϥϜμ
    4 : proceedϝιουͱasyncؔ਺ͷྫ

    View Slide

  80. Proceedϝιου
    w ݱࡏ࣮ߦதͷϥϜμࣜΛҰ࣌தஅ͠৽͍͠ίϧʔνϯΛ

    ։࢝ͯ͠ޙஈͷύΠϓϥΠϯΛ࣮ߦ͢Δ"1*

    w ޙஈͷύΠϓϥΠϯͷॲཧ͕׬ྃ͢ΔͱQSPDFFE
    Λ࣮ߦ

    ͨ͠ϥϜμࣜͷॲཧ͕࠶։͞ΕΔ

    View Slide

  81. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    QSPDFFE
    Λ࣮ߦ͢ΔϥϜμ

    View Slide

  82. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 5ISFBEᶃͰϦΫΤετΛϋϯυϦϯάͯ͠

    5ISFBEᶄ্ͰίϧʔνϯΛ։࢝

    ͦͷ··5ISFBEᶄ্ͷίϧʔνϯͰ1JQFMJOFΛ࣮ߦ

    View Slide

  83. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    w 5ISFBEᶄ্Ͱίϧʔνϯ͕4FUVQϑΣΠζͷॲཧΛ࣮ߦ
    ॲཧΛ࣮ߦ
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }

    View Slide

  84. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕ऴྃ ॲཧΛ࣮ߦ
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    {
    getAuth(userID)
    }
    w 4FUVQϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ

    ίϧʔνϯ͕.POJUPSJOHϑΣΠζͷॲཧΛ࣮ߦ
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    QSPDFFE
    Λ࣮ߦ͢ΔϥϜμ

    View Slide

  85. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    w BTZODؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝

    5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ
    BTZODؔ਺Λ࣮ߦ
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }

    View Slide

  86. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    w BTZODؔ਺ʹΑͬͯ5ISFBEᶅ্ͰίϧʔνϯΛ։࢝

    5ISFBEᶄͱ5ISFBEᶅͷͦΕͧΕͰॲཧΛ࣮ߦ
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ ࢒ΓͷॲཧΛ࣮ߦ
    5ISFBEᶅͰ࣮ߦத
    QSPDFFE
    Λ࣮ߦ͢ΔϥϜμ

    View Slide

  87. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ
    w 5ISFBEᶄ্ͰQSPDFFEΛ࣮ߦ͢Δͱ5ISFBEᶅ্ͷίϧʔνϯͷ
    ׬ྃΛ଴ͨͣʹ.POJUPSJOHϑΣΠζΛҰ࣌தஅͰ͖Δ
    ॲཧΛҰ࣌தஅ
    QSPDFFE
    Λ࣮ߦ͢ΔϥϜμ
    5ISFBEᶅͰ࣮ߦத

    View Slide

  88. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧΛ࣮ߦ
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ
    w 5ISFBEᶄͷ.POJUPSJOHϑΣΠζΛҰ࣌தஅͯ͠

    ͦͷ··5ISFBEᶄ্Ͱ$BMMϑΣΠζͷ࣮ߦΛ։࢝
    ॲཧΛҰ࣌தஅ
    5ISFBEᶅͰ࣮ߦத

    View Slide

  89. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧΛ࣮ߦ
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    w $BMMϑΣΠζͷॲཧ͕׬ྃͨ͠Β࣍ʹ5ISFBEᶄ্Ͱ

    ίϧʔνϯ͕4FOEϑΣΠζͷॲཧΛ࣮ߦ
    ॲཧΛҰ࣌தஅ
    5ISFBEᶅͰ࣮ߦத

    View Slide

  90. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧΛ࣮ߦ
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    w 5ISFBEᶄ্Ͱ4FOEϑΣΠζͷॲཧΛ࣮ߦ͍ͯ͠Δؒʹ

    5ISFBEᶅ্ͷίϧʔνϯͷॲཧ͕׬ྃ
    ॲཧΛҰ࣌தஅ
    5ISFBEᶅͰॲཧ͕ऴྃ

    View Slide

  91. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 4FOEϑΣΠζͷॲཧ͕׬ྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ͸

    .POJUPSJOHϑΣΠζͷॲཧΛ࠶։͢Δ
    ॲཧΛ࠶։
    5ISFBEᶅͰॲཧ͕ऴྃ

    View Slide

  92. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 4FOEϑΣΠζͷॲཧ͕׬ྃͨ͠Β5ISFBEᶄ্ͷίϧʔνϯ͸

    .POJUPSJOHϑΣΠζͷॲཧΛ࠶։͢Δ
    ࢒ΓͷॲཧΛ࣮ߦ
    5ISFBEᶅͰॲཧ͕ऴྃ

    View Slide

  93. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧ͕ऴྃ
    ॲཧ͕ऴྃ ॲཧ͕ऴྃ ॲཧ͕ऴྃ
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 5ISFBEᶄ্ͷίϧʔνϯ͕ऴྃͨ͠Β

    ݺͼग़͠ݩͷ5ISFBEᶃͷ໭ͬͯϋϯυϦϯά͕ऴྃ
    5ISFBEᶅͰॲཧ͕ऴྃ

    View Slide

  94. 4 : proceedϝιουͱasyncؔ਺ͷྫ
    w ,UPS͔Βఏڙ͞Ε͍ͯΔQSPDFFEϝιουΛ࢖͏͜ͱͰ

    ผεϨουͷίϧʔνϯ͔ΒͷฦΓ஋Λ଴͍ͬͯΔؒʹ

    ޙଓͷผͷύΠϓϥΠϯͷॲཧΛ࣮ߦ͢Δ͜ͱ͕Ͱ͖Δ
    w ֤ύΠϓϥΠϯϑΣΠζͰͷϥϜμࣜΛ

    ผͷ'FBUVSFͰಠཱʹఆٛ͠ͳ͕Β΋

    ύΠϓϥΠϯϑΣΠζΛލ͍ͰඇಉظॲཧΛ࣮ߦ͢Δ͜ͱͰ

    ΑΓޮ཰తʹܭࢉΛߦ͏͜ͱ͕Ͱ͖Δ

    View Slide

  95. $PSPVUJOFTͷ௿Ϩϕϧ"1*
    ,UPSͱඇಉظॲཧύΠϓϥΠϯ
    ,UPSΛ$PSPVUJOFTͰඥղ͘
    ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ
    ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

    View Slide

  96. Coroutinesͷ௿Ϩϕϧͳૢ࡞
    w $PSPVUJOFΛγϯϓϧʹ࢖͏͚ͩͳΒҙࣝͤͣͱ΋ࠔΒͳ͍

    ͜ͱ͕ଟ͍͕ϥΠϒϥϦΛ࡞Δͱ͖ͳͲ͸ѻ͑Δͱ໾ཱͭ
    w $POUJOVBUJPOTVTQFOEؔ਺ͷࣗಈมܗ
    w TUBSU$PSPVUJOF

    TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSO
    w TVTQFOE$PSPVUJOF6OJOUFSDFQUFE0S3FUVSO

    View Slide

  97. Continuation (ܧଓ)
    w TVTQFOEؔ਺Ͱதஅ͞Εͨίϧʔνϯͷঢ়ଶ
    w தஅ͞Εͨ෦෼Ҏ߱ͷ࢒Γͷॲཧ ίʔϧόοΫ
    Λද͢
    w SFTVNF8JUIϝιου͸׬ྃίʔϧόοΫͰ͋Γ

    ίϧʔνϯͷ׬ྃ࣌ʹ੒ޭɾࣦഊͷ͍ͣΕ͔Λฦ͢
    public interface Continuation {
    public val context: CoroutineContext
    public fun resumeWith(result: Result)
    }

    View Slide

  98. suspendؔ਺
    suspend fun susFuncA() {
    delay(1000L)
    }
    val block: suspend () -> Unit = {}
    w ؔ਺಺ͰଞͷTVTQFOEؔ਺Λݺͼग़͢͜ͱͰ

    ࣮ߦεϨουΛϒϩοΫͤͣʹ

    ίʔυ࣮ߦΛதஅ͢ΔՄೳੑͷ͋Δؔ਺
    w TVTQFOEؔ਺͸ଞͷTVTQFOEؔ਺͔ΒͷΈݺͼग़͢͜ͱ͕Մೳ
    TVTQFOEؔ਺ϥϜμ
    fun normalFunc() {
    susFuncA(1000L)
    }
    ௨ৗͷؔ਺͔Βͷݺͼग़͠

    View Slide

  99. suspendؔ਺
    suspend fun susFuncA() {
    delay(1000L)
    }
    val block: suspend () -> Unit = {}
    w ؔ਺಺ͰଞͷTVTQFOEؔ਺Λݺͼग़͢͜ͱͰ

    ࣮ߦεϨουΛϒϩοΫͤͣʹ

    ίʔυ࣮ߦΛதஅ͢ΔՄೳੑͷ͋Δؔ਺
    w TVTQFOEؔ਺͸ଞͷTVTQFOEؔ਺͔ΒͷΈݺͼग़͢͜ͱ͕Մೳ
    TVTQFOEؔ਺ϥϜμ
    fun normalFunc() {
    susFuncA(1000L)
    }
    ௨ৗͷؔ਺͔Βͷݺͼग़͠
    ͳͥTVTQFOEؔ਺͸

    ௨ৗͷؔ਺͔Βݺͼग़͢͜ͱ͕ग़དྷͳ͍ͷ͔ʁ

    View Slide

  100. suspendؔ਺
    suspend fun susFunc(
    time: Long
    ) : String
    TVTQFOEؔ਺
    fun susFunc(
    time: Long,
    continuation: Continuation
    ) : Any?
    ੜ੒͞ΕΔίʔυ ٙࣅίʔυ

    w TVTQFOEम০ࢠ͸ίϯύΠϧ࣌ʹผͷؔ਺ʹม׵͞ΕΔ
    ˞࣮ࡍ͸TVTQFOEؔ਺಺ͷίʔυ΋γάχνϟ͕มߋ͞ΕͨΓ

    ঢ়ଶΫϥε͕ੜ੒͞ΕͨΓ͍ͯ͠Δ఺ʹ஫ҙɻ

    View Slide

  101. suspend fun susFunc(
    time: Long
    ) : String {
    delay(time)
    return "Kotlin Fest!"
    }
    TVTQFOEؔ਺

    View Slide

  102. suspend fun susFunc(
    time: Long,
    continuation: Continuation
    ) : Any? {
    val call_back = when(continuation){
    is ... -> continuation
    else -> ...
    }
    when(call_back.lable){
    1 -> {
    call_back.lable = 2
    return delay(time, call_back)
    }
    2 -> { return "Kotlin Fest!" }
    }
    }
    suspend fun susFunc(
    time: Long
    ) : String {
    delay(time)
    return "Kotlin Fest!"
    }
    TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ

    View Slide

  103. (suspend) fun susFunc(
    time: Long,
    continuation: Continuation
    ) : Any? {
    val call_back = when(continuation){
    is ... -> continuation
    else -> ...
    }
    when(call_back.lable){
    1 -> {
    call_back.lable = 2
    return delay(time, call_back)
    }
    2 -> { return "Kotlin Fest!" }
    }
    }
    suspend fun susFunc(
    time: Long
    ) : String {
    delay(time)
    return "Kotlin Fest!"
    }
    TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ

    View Slide

  104. (suspend) fun susFunc(
    time: Long,
    continuation: Continuation
    ) : Any? {
    val call_back = when(continuation){
    is ... -> continuation
    else -> ...
    }
    when(call_back.lable){
    1 -> {
    call_back.lable = 2
    return delay(time, call_back)
    }
    2 -> { return "Kotlin Fest!" }
    }
    }
    suspend fun susFunc(
    time: Long
    ) : String {
    delay(time)
    return "Kotlin Fest!"
    }
    TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ

    ᶃҾ਺ʹ$POUJOVBUJPO͕௥Ճ͞Ε͍ͯΔ

    ᶄฦΓ஋͕"OZ ܕʹͳ͍ͬͯΔ

    View Slide

  105. (suspend) fun susFunc(
    time: Long,
    continuation: Continuation
    ) : Any? {
    val call_back = when(continuation){
    is ... -> continuation
    else -> ...
    }
    when(call_back.lable){
    1 -> {
    call_back.lable = 2
    return delay(time, call_back)
    }
    2 -> { return "Kotlin Fest!" }
    }
    }
    suspend fun susFunc(
    time: Long
    ) : String {
    delay(time)
    return "Kotlin Fest!"
    }
    TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ

    ᶅ಺෦Ͱݺͼग़͍ͯ͠ΔTVTQFOEؔ਺ͷҾ਺ʹ΋
    $POUJOVBUJPO͕௥Ճ͞Ε͍ͯͯ

    ࣗ਎͕ड͚औͬͨ$POUJOVBUJPOΛ౉͍ͯ͠Δ

    View Slide

  106. (suspend) fun susFunc(
    time: Long,
    continuation: Continuation
    ) : Any? {
    val call_back = when(continuation){
    is ... -> continuation
    else -> ...
    }
    when(call_back.lable){
    1 -> {
    call_back.lable = 2
    return delay(time, call_back)
    }
    2 -> { return "Kotlin Fest!" }
    }
    }
    suspend fun susFunc(
    time: Long
    ) : String {
    delay(time)
    return "Kotlin Fest!"
    }
    TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ

    ௨ৗͷؔ਺͔ΒTVTQFOEؔ਺Λݺͼग़ͦ͏ͱͯ͠΋

    $POUJOVBUJPOΛҾ਺ͱͯ͠౉͢͜ͱ͕Ͱ͖ͳ͍

    View Slide

  107. (suspend) fun susFunc(
    time: Long,
    continuation: Continuation
    ) : Any? {
    val call_back = when(continuation){
    is ... -> continuation
    else -> ...
    }
    when(call_back.lable){
    1 -> {
    call_back.lable = 2
    return delay(time, call_back)
    }
    2 -> { return "Kotlin Fest!" }
    }
    }
    suspend fun susFunc(
    time: Long
    ) : String {
    delay(time)
    return "Kotlin Fest!"
    }
    TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ

    View Slide

  108. (suspend) fun susFunc(
    time: Long,
    continuation: Continuation
    ) : Any? {
    val call_back = when(continuation){
    is ... -> continuation
    else -> ...
    }
    when(call_back.lable){
    1 -> {
    call_back.lable = 2
    return delay(time, call_back)
    }
    2 -> { return "Kotlin Fest!" }
    }
    }
    suspend fun susFunc(
    time: Long
    ) : String {
    delay(time)
    return "Kotlin Fest!"
    }
    TVTQFOEؔ਺ ੜ੒͞ΕΔίʔυ ٙࣅίʔυ

    Ͱ͸Ͳ͏΍ͬͯ࠷ॳͷTVTQFOEؔ਺Λ

    ී௨ͷؔ਺͔Βݺͼग़͢ʁ

    ίϧʔνϯΛ։࢝͢Δʁ

    View Slide

  109. startCoroutine
    w ίϧʔνϯΛ࡞੒ͯ͠ݱࡏͷεϨουͰ

    ϨγʔόʔͰ͋ΔTVTQFOEϥϜμΛ࣮ߦ͢Δ
    w MBVODI BTZODͳͲͷίϧʔνϯϏϧμʔ΋

    ಺෦తʹݺͼग़ͯ͠ίϧʔνϯΛ࡞੒͍ͯ͠Δ
    public fun (suspend () -> T).startCoroutine(
    completion: kotlin.coroutines.Continuation
    ): kotlin.Unit { /* compiled code */ }

    View Slide

  110. val continuation = object : Continuation {
    override val context:
    CoroutineContext = EmptyCoroutineContext
    override fun resumeWith(result: Result){ ɾɾɾ }
    }
    suspend { delay(1000L) }.startCoroutine(continuation)
    w TVTQFOEϥϜμͷ֦ுؔ਺ͱͯ͠ఆٛ͞Ε͍ͯͯ

    TVTQFOEؔ਺Ҏ֎ͷ௨ৗͷؔ਺͔Β΋ݺͼग़͕͠Մೳ
    w $POUJOVBUJPO͸ࣗલͰ༻ҙ͢Δ͔

    طʹ։͍࢝ͯ͠Δίϧʔνϯ͔Βऔಘ͢Δ

    View Slide

  111. val continuation = object : Continuation {
    override val context:
    CoroutineContext = EmptyCoroutineContext
    override fun resumeWith(result: Result){ ɾɾɾ }
    }
    suspend { delay(1000L) }.startCoroutine(continuation)
    w TVTQFOEϥϜμͷ֦ுؔ਺ͱͯ͠ఆٛ͞Ε͍ͯͯ

    TVTQFOEؔ਺Ҏ֎ͷ௨ৗͷؔ਺͔Β΋ݺͼग़͕͠Մೳ
    w $POUJOVBUJPO͸ࣗલͰ༻ҙ͢Δ͔

    طʹ։͍࢝ͯ͠Δίϧʔνϯ͔Βऔಘ͢Δ

    View Slide

  112. inline fun (suspend () -> T).startCoroutineUninterceptedOrReturn(
    completion: Continuation
    ): Any? = (this as Function1, Any?>).invoke(completion)
    public fun (suspend () -> T).startCoroutine(
    completion: kotlin.coroutines.Continuation
    ): kotlin.Unit { /* compiled code */ }
    startCoroutineUninterceptedOrReturn
    w TUBSU$PSPVUJOFͱҧ͍ɺฦΓ஋Λड͚औΔ
    w ࣮ߦͨ͠TVTQFOEؔ਺͕಺෦ͷதஅ఺Ͱதஅ͞ΕΔͱ

    $03065*/&@4641&/%&%ϚʔΧʔΛฦ͢

    View Slide

  113. inline fun (suspend () -> T).startCoroutineUninterceptedOrReturn(
    completion: Continuation
    ): Any? = (this as Function1, Any?>).invoke(completion)
    public fun (suspend () -> T).startCoroutine(
    completion: kotlin.coroutines.Continuation
    ): kotlin.Unit { /* compiled code */ }
    startCoroutineUninterceptedOrReturn
    w TUBSU$PSPVUJOFͱҧ͍ɺฦΓ஋Λड͚औΔ
    w ࣮ߦͨ͠TVTQFOEؔ਺͕಺෦ͷதஅ఺Ͱதஅ͞ΕΔͱ

    $03065*/&@4641&/%&%ϚʔΧʔΛฦ͢

    View Slide

  114. inline fun (suspend () -> T).startCoroutineUninterceptedOrReturn(
    completion: Continuation
    ): Any? = (this as Function1, Any?>).invoke(completion)
    internal enum class CoroutineSingletons {
    COROUTINE_SUSPENDED, UNDECIDED, RESUMED
    }
    startCoroutineUninterceptedOrReturn
    w TUBSU$PSPVUJOFͱҧ͍ɺฦΓ஋Λड͚औΔ
    w ࣮ߦͨ͠TVTQFOEؔ਺͕಺෦ͷதஅ఺Ͱதஅ͞ΕΔͱ

    $03065*/&@4641&/%&%ϚʔΧʔΛฦ͢

    View Slide

  115. inline fun (suspend () -> T).startCoroutineUninterceptedOrReturn(
    completion: Continuation
    ): kotlin.Any? { /* compiled code */ }
    internal enum class CoroutineSingletons {
    COROUTINE_SUSPENDED, UNDECIDED, RESUMED
    }
    startCoroutineUninterceptedOrReturn
    w TUBSU$PSPVUJOFͱҧ͍ɺฦΓ஋Λड͚औΔ
    w ࣮ߦͨ͠TVTQFOEؔ਺͕಺෦ͷதஅ఺Ͱதஅ͞ΕΔͱ

    $03065*/&@4641&/%&%ϚʔΧʔΛฦ͢
    ίϧʔνϯʹ౉͞Ε͍ͯΔ

    Continuation͸Ͳ͏΍ͬͯऔಘͰ͖Δʁ

    View Slide

  116. suspendCoroutineUninterceptedOrReturn
    w ίϧʔνϯ಺ͰݺͿ͜ͱͰίϧʔνϯ͕தஅͨ͠࢒Γͷঢ়ଶΛ

    $POUJOVBUJPOΠϯελϯεͱͯ͠औಘͰ͖Δ"1*
    w ϥϜμࣜͰ$POUJOVBUJPOΠϯελϯεΛࢀর͠

    ίϧʔνϯͷதஅɾ׬ྃͱ͍ͬͨঢ়ଶΛ௚઀੍ޚͰ͖Δ
    suspend inline fun suspendCoroutineUninterceptedOrReturn(
    crossinline block: (Continuation) -> Any?
    ): T

    View Slide

  117. w ίϧʔνϯΛதஅঢ়ଶͱͯ͠ҡ࣋͢Δ৔߹

    $03065*/&@4641&/%&%ϚʔΧʔΛฦ͢
    w ίϧʔνϯΛ׬ྃ͢Δ৔߹

    ݁ՌΛSFTVNF8JUIϝιουʹ౉࣮ͯ͠ߦ
    suspend inline fun suspendCoroutineUninterceptedOrReturn(
    crossinline block: (Continuation) -> Any?
    ): T
    suspendCoroutineUninterceptedOrReturn

    View Slide

  118. $PSPVUJOFTͷ௿Ϩϕϧ"1*
    ,UPSͱඇಉظॲཧύΠϓϥΠϯ
    ,UPSΛ$PSPVUJOFTͰඥղ͘
    ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ
    ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

    View Slide

  119. KtorΛCoroutinesͰඥղ͘
    w ύϑΥʔϚϯεΛߟྀͨ͠$PSPVUJOFͷੜ੒
    w QSPDFFEؔ਺ͷॲཧΛͲ͏΍࣮ͬͯݱ͍ͯ͠Δͷ͔
    w $PSPVUJOFΛ։࢝͢Δͱ͖ʹ$POUJOVBUJPO͚ͩͰͳ͘

    ೚ҙͷΦϒδΣΫτ΋Ҿ͖౉͢ํ๏

    View Slide

  120. ύϑΥʔϚϯεΛߟྀͨ͠Coroutineͷੜ੒
    4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    delay(1000L)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }

    View Slide

  121. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    delay(1000L)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 5ISFBEᶄ্Ͱ։࢝ͨ͠࠷ॳͷίϧʔνϯ͕

    ֤1JQFMJOF1IBTFຖʹ౎౓ίϧʔνϯΛੜ੒͍ͯ͠Δ

    ͦΕΒ͸શͯ5ISFBEᶄ্Ͱಈ࡞͢Δ
    ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%

    View Slide

  122. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 5ISFBEᶄ্Ͱ։࢝ͨ͠࠷ॳͷίϧʔνϯ͕

    ֤1JQFMJOF1IBTFຖʹ౎౓ίϧʔνϯΛੜ੒͍ͯ͠Δ

    ͦΕΒ͸શͯ5ISFBEᶄ্Ͱಈ࡞͢Δ
    ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%
    1IBTFຖʹίϧʔνϯΛ

    ੜ੒͢Δ͜ͱʹΑͬͯ

    1IBTFຖʹதஅॲཧ΍ΩϟϯηϧΛ

    ੍ޚ͢Δ͜ͱ͕Ͱ͖Δ

    View Slide

  123. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 5ISFBEᶄ্Ͱ։࢝ͨ͠࠷ॳͷίϧʔνϯ͕

    ֤1JQFMJOF1IBTFຖʹ౎౓ίϧʔνϯΛੜ੒͢Δ͍ͯ͠Δ

    ͦΕΒ͸શͯ5ISFBEᶄ্Ͱಈ࡞͢Δ
    ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%
    ܰྔͱ͸͍͑

    ϦΫΤετͷ౓ʹେྔʹ

    ίϧʔνϯΛੜ੒͍ͯͯ͠

    ύϑΥʔϚϯεʹӨڹ͸ͳ͍ͷʁ

    View Slide

  124. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    delay(1000L)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w 5ISFBEᶄ্Ͱ։࢝ͨ͠࠷ॳͷίϧʔνϯ͕

    ֤1JQFMJOF1IBTFຖʹ౎౓ίϧʔνϯΛੜ੒͍ͯ͠Δ

    ͦΕΒ͸શͯ5ISFBEᶄ্Ͱಈ࡞͢Δ
    ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%

    View Slide

  125. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w ࠷ॳͷίϧʔνϯ͸֤1IBTFίϧʔνϯΛ࡞੒͢Δࡍʹ

    ৽ͨʹ$POUJOVBUJPOΛ࡞Βͣɺࣗ਎ͷ$POUJOVBUJPOΛ

    Ҿ͖౉͍ͯ͠Δ
    ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%

    View Slide

  126. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%
    suspend inline fun suspendCoroutineUninterceptedOrReturn(
    crossinline block: (Continuation) -> Any?
    ): T
    w TVTQFOE$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOؔ਺Λ࢖͏ͱ

    ࣮ߦதͷίϧʔνϯͷ$POUJOVBUJPOΛऔΓग़ͯ͠

    Ҿ਺ͷϥϜμࣜͷதͰѻ͏͜ͱ͕Ͱ͖Δ

    View Slide

  127. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w TVTQFOE$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOؔ਺Λ࢖͏ͱ

    ࣮ߦதͷίϧʔνϯͷ$POUJOVBUJPOΛऔΓग़ͯ͠

    Ҿ਺ͷϥϜμࣜͷதͰѻ͏͜ͱ͕Ͱ͖Δ
    ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%
    suspend inline fun suspendCoroutineUninterceptedOrReturn(
    crossinline block: (Continuation) -> Any?
    ): T

    View Slide

  128. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOؔ਺ͷҾ਺ʹ

    $POUJOVBUJPOΛ౉͢ͱ৽ͨʹ$POUJOVBUJPOΛ

    ࡞੒ͤͣʹίϧʔνϯΛ։࢝Ͱ͖Δ
    ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%
    inline fun (suspend () -> T).startCoroutineUninterceptedOrReturn(
    completion: Continuation
    ): kotlin.Any?

    View Slide

  129. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%
    inline fun (suspend () -> T).startCoroutineUninterceptedOrReturn(
    completion: Continuation
    ): kotlin.Any?
    w TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOؔ਺ͷҾ਺ʹ

    $POUJOVBUJPOΛ౉͢ͱ৽ͨʹ$POUJOVBUJPOΛ

    ࡞੒ͤͣʹίϧʔνϯΛ։࢝Ͱ͖Δ

    View Slide

  130. suspendCoroutineUninterceptedOrReturn { continuation ->
    do {
    val rc = PhaseʹׂΓ౰ͯΒΕͨϥϜμࣜ.
    startCoroutineUninterceptedOrReturn(ɾɾɾ)
    ɾɾɾ
    } while (true)
    COROUTINE_SUSPENDED
    }
    w TVTQFOE$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOͱ

    TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOΛ૊Έ߹ΘͤΔ͜ͱͰ

    $POUJOVBUJPOΛڞ༗͠ͳ͕ΒίϧʔνϯΛ࡞੒͍ͯ͠Δ

    View Slide

  131. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    delay(1000L)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w $POUJOVBUJPOΛڞ༗ͯ͠ίϧʔνϯͷੜ੒ίετΛ཈͑Δ͜ͱͰ

    ύΠϓϥΠϯͷ࣮ߦ଎౓ͷύϑΥʔϚϯεΛ޲্͍ͯ͠Δ
    ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%

    View Slide

  132. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w $POUJOVBUJPOΛڞ༗ͯ͠ίϧʔνϯͷੜ੒ίετΛ཈͑Δ͜ͱͰ

    ύΠϓϥΠϯͷ࣮ߦ଎౓ͷύϑΥʔϚϯεΛ޲্͍ͯ͠Δ
    ίϧʔνϯ" ίϧʔνϯ# ίϧʔνϯ$ ίϧʔνϯ%
    TVTQFOE$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOͱ

    TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOΛ

    ૊Έ߹ΘͤͰίϧʔνϯͷੜ੒ίετΛ཈͑Δํ๏͸

    (FOFSBUPSTͷZJFMEؔ਺ͷ಺෦࣮૷Ͱ΋࢖ΘΕ͍ͯΔ

    View Slide

  133. proceedؔ਺ͷ࣮૷
    4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    QSPDFFE
    Λ࣮ߦ͢ΔϥϜμ

    View Slide

  134. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    ॲཧΛ࣮ߦ
    {
    val id = async {
    delay(1000L)

    “Finish”
    }

    proceed()
    logging(id.await())
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    ॲཧ͕ऴྃ
    w QSPDFFEϝιουΛ࣮ߦ͢Δͱ֘౰ϑΣΠζͷॲཧΛதஅͯ͠

    ޙଓͷύΠϓϥΠϯͷॲཧΛ࣮ߦͰ͖Δ
    ॲཧΛҰ࣌தஅ
    5ISFBEᶅͰ࣮ߦத

    View Slide

  135. suspendCoroutineUninterceptedOrReturn { continuation ->
    do {
    ɾɾɾ
    val rc = PhaseʹׂΓ౰ͯΒΕͨϥϜμࣜ.
    startCoroutineUninterceptedOrReturn(ɾɾɾ)
    ɾɾɾ
    } while (true)
    COROUTINE_SUSPENDED
    }
    w QSPDFFEϝιουΛ࣮ߦ͢Δͱ$POUJOVBUJPOΛ৽ͨʹ࡞੒ͯ͠

    ผεϨουͰಈ࡞͢ΔίϧʔνϯΛ։࢝͢Δ

    View Slide

  136. private val continuation: Continuation
    = object : Continuation, CoroutineStackFrame {
    ɾɾɾ
    override val context: CoroutineContext
    get () {
    val cont = rootContinuation
    return when (cont) {
    null -> throw IllegalStateException("Not started")
    is Continuation<*> -> cont.context
    is List<*> ->
    (cont as List>).last().context
    else -> throw IllegalStateException("e")
    }
    }
    }

    View Slide

  137. private val continuation: Continuation
    = object : Continuation, CoroutineStackFrame {
    ɾɾɾ
    override val context: CoroutineContext
    get () {
    val cont = rootContinuation
    return when (cont) {
    null -> throw IllegalStateException("Not started")
    is Continuation<*> -> cont.context
    is List<*> ->
    (cont as List>).last().context
    else -> throw IllegalStateException("e")
    }
    }
    }

    View Slide

  138. ಠࣗͷCoroutineStart
    4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    delay(1000L)
    }
    {
    delay(1000L)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }

    View Slide

  139. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w ΞϓϦέʔγϣϯ΍ϦΫΤετɺϨεϙϯεͷ৘ใΛ

    ϛϡʔλϒϧʹอ࣋ͨ͠"QQMJDBUJPO$BMMΦϒδΣΫτΛ

    ֤1JQFMJOF1IBTFؒͰڞ༗͍ͯ͠Δ
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    "QQMJDBUJPO$BMM

    View Slide

  140. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w "QQMJDBUJPO$BMM͸ύΠϓϥΠϯ಺ʹάϩʔόϧͳม਺ͱͯ͠

    ڞ༗͞ΕΔͷͰ͸ͳ͘ɺ1JQFMJOF1IBTFຖͷίϧʔνϯੜ੒࣌ʹ

    $POUJOVBUJPOͱҰॹʹҾ͖౉͍ͯ͠Δ
    "QQMJDBUJPO$BMM

    View Slide

  141. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }
    w "QQMJDBUJPO$BMM͸ύΠϓϥΠϯ಺ʹάϩʔόϧͳม਺ͱͯ͠

    ڞ༗͞ΕΔͷͰ͸ͳ͘ɺ1JQFMJOF1IBTFຖͷίϧʔνϯੜ੒࣌ʹ

    $POUJOVBUJPOͱҰॹʹҾ͖౉͍ͯ͠Δ
    "QQMJDBUJPO$BMM
    ίϧʔνϯΛ։࢝͢Δͱ͖ʹ

    $POUJOVBUJPOҎ֎ͷΦϒδΣΫτΛ

    Ͳ͏΍ͬͯ౉͢ͷ͔ʁ

    View Slide

  142. public inline fun (suspend () -> T).
    startCoroutineUninterceptedOrReturn(
    completion: kotlin.coroutines.Continuation
    ): kotlin.Any? { /* compiled code */ }
    public inline fun (suspend R.() -> T).
    startCoroutineUninterceptedOrReturn(
    receiver: R,
    completion: kotlin.coroutines.Continuation
    ): kotlin.Any? { /* compiled code */ }
    w TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOΛ࢖͏ͱ

    ৽ͨʹίϧʔνϯΛੜ੒͢Δͱ͖ʹ$POUJOVBUJPOΛҾ਺ͱͯ͠

    ౉͢͜ͱͰίϧʔνϯؒͰ$POUJOVBUJPOΛڞ༗Ͱ͖Δ

    View Slide

  143. public inline fun (suspend () -> T).
    startCoroutineUninterceptedOrReturn(
    completion: kotlin.coroutines.Continuation
    ): kotlin.Any? { /* compiled code */ }
    public inline fun (suspend R.() -> T).
    startCoroutineUninterceptedOrReturn(
    receiver: R,
    completion: kotlin.coroutines.Continuation
    ): kotlin.Any? { /* compiled code */ }
    w $POUJOVBUJPOΛίϧʔνϯʹ౉͢"1*͔͠ެ։͞Ε͍ͯͳ͍

    ͦͷͨΊίϧʔνϯ։࢝࣌ʹ"QQMJDBUJPO$BMM΋Ҿ͖౉͢͜ͱ͸

    ௨ৗ͸ෆՄೳ

    View Slide

  144. internal actual inline fun
    (suspend R.(A) -> Unit).startCoroutineUninterceptedOrReturn3(
    receiver: R,
    arg: A,
    continuation: Continuation
    ): Any? {
    val function = (this as Function3, Any?>)
    return function.invoke(receiver, arg, continuation)
    }
    w ,UPSͰ͸$POUJOVBUJPOʹՃ͑ͯ೚ҙͷܕͷΦϒδΣΫτΛ

    Ҿ͖౉ͯ͠৽ͨʹίϧʔνϯΛ։࢝͢Δؔ਺Λಠ࣮ࣗ૷͍ͯ͠Δ
    w ૊ΈࠐΈؔ਺ͱ͍ۙॲཧΛҎԼͷؔ਺Ͱ࣮ݱ͍ͯ͠Δ

    View Slide

  145. public inline fun (suspend R.() -> T).
    startCoroutineUninterceptedOrReturn(
    receiver: R,
    completion: kotlin.coroutines.Continuation
    ): kotlin.Any? { /* compiled code */ }
    internal actual inline fun
    (suspend R.(A) -> Unit).startCoroutineUninterceptedOrReturn3(
    receiver: R,
    arg: A,
    continuation: Continuation
    ): Any? {
    val function = (this as Function3, Any?>)
    return function.invoke(receiver, arg, continuation)
    }
    ϥΠϒϥϦ͔Βఏڙ͞Ε͍ͯΔؔ਺
    ,UPSͰಠ࣮ࣗ૷͍ͯ͠Δίϧʔνϯ։࢝"1*

    View Slide

  146. public inline fun (suspend R.() -> T).
    startCoroutineUninterceptedOrReturn(
    receiver: R,
    completion: kotlin.coroutines.Continuation
    ): kotlin.Any? { /* compiled code */ }
    internal actual inline fun
    (suspend R.(A) -> Unit).startCoroutineUninterceptedOrReturn3(
    receiver: R,
    arg: A,
    continuation: Continuation
    ): Any? {
    val function = (this as Function3, Any?>)
    return function.invoke(receiver, arg, continuation)
    }
    ,UPSͰಠ࣮ࣗ૷͍ͯ͠Δίϧʔνϯ։࢝"1*
    ϥΠϒϥϦ͔Βఏڙ͞Ε͍ͯΔؔ਺

    View Slide

  147. internal actual inline fun
    (suspend R.(A) -> Unit).startCoroutineUninterceptedOrReturn3(
    receiver: R,
    arg: A,
    continuation: Continuation
    ): Any? {
    val function = (this as Function3, Any?>)
    return function.invoke(receiver, arg, continuation)
    }
    w Ҿ਺Λ"ܕ͔͠ड͚औΒͳ͍͸ͣͷϥϜμࣜ UIJT
    ͕Կނ͔

    Ҿ਺ͱͯ͠"ܕɾ$POUJOVBUJPOͷ̎ͭΛड͚औΔ'VODUJPOܕʹ

    Ωϟετ͞Ε͔ͯΒ࣮ߦ͞Ε͍ͯΔ

    View Slide

  148. internal actual inline fun
    ((suspend) R.(A, Continuation) -> Unit).
    startCoroutineUninterceptedOrReturn3(
    receiver: R,
    arg: A,
    continuation: Continuation
    ): Any? {
    val function = (this as Function3, Any?>)
    return function.invoke(receiver, arg, continuation)
    }
    w ࣮͸ϥϜμࣜ UIJT
    ͸TVTQFOEϥϜμͳͷͰίϯύΠϧ࣌ʹ͸

    Ҿ਺ͱͯ͠$POUJOVBUJPO΋ड͚औΔϥϜμࣜʹม׵͞ΕΔʂ
    w ͕࣮ͨͬͯ͠ߦ࣌ͷΩϟετ͸੒ޭ͢Δ
    ੜ੒͞ΕΔίʔυ ٙࣅίʔυ

    View Slide

  149. internal actual inline fun
    ((suspend) R.(A, Continuation) -> Unit).
    startCoroutineUninterceptedOrReturn3(
    receiver: R,
    arg: A,
    continuation: Continuation
    ): Any? {
    val function = (this as Function3, Any?>)
    return function.invoke(receiver, arg, continuation)
    }
    w ࣮͸ϥϜμࣜ UIJT
    ͸TVTQFOEϥϜμͳͷͰίϯύΠϧ࣌ʹ͸

    Ҿ਺ͱͯ͠$POUJOVBUJPO΋ड͚औΔϥϜμࣜʹม׵͞ΕΔʂ
    w ͕࣮ͨͬͯ͠ߦ࣌ͷΩϟετ͸੒ޭ͢Δ
    ੜ੒͞ΕΔίʔυ ٙࣅίʔυ

    ίϯύΠϧޙͷίʔυͷγάωνϟΛ

    ༧ଌͯ͠ڧ੍Ωϟετ͍ͤͯ͞Δ

    View Slide

  150. internal actual inline fun
    ((suspend) R.(A, Continuation) -> Unit).
    startCoroutineUninterceptedOrReturn3(
    receiver: R,
    arg: A,
    continuation: Continuation
    ): Any? {
    val function = (this as Function3, Any?>)
    return function.invoke(receiver, arg, continuation)
    }
    w ࣮͸ϥϜμࣜ UIJT
    ͸TVTQFOEϥϜμͳͷͰίϯύΠϧ࣌ʹ͸

    Ҿ਺ͱͯ͠$POUJOVBUJPO΋ड͚औΔϥϜμࣜʹม׵͞ΕΔʂ
    w ͕࣮ͨͬͯ͠ߦ࣌ͷΩϟετ͸੒ޭ͢Δ
    ੜ੒͞ΕΔίʔυ ٙࣅίʔυ

    ࣮͸TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSOͷ

    ࣮૷Ͱಉ͜͡ͱ͕ߦΘΕ͍ͯΔ


    ͜ͷํ๏Λࢀߟʹ͢Δͱ

    ೚ҙͷ਺ͷҾ਺Λίϧʔνϯ։࢝࣌ʹ

    ౉͢Α͏ͳ௿Ϩϕϧ"1*Λ

    ࣗ෼Ͱ࣮૷͢Δ͜ͱ͕Ͱ͖Δ

    View Slide

  151. ·ͱΊ

    View Slide

  152. $PSPVUJOFTͷ௿Ϩϕϧ"1*ؔ਺
    ,UPSͱඇಉظॲཧύΠϓϥΠϯ
    ,UPSΛ$PSPVUJOFTͰඥղ͘
    ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ
    ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝

    View Slide

  153. 4FUVQ $BMM 4FOE
    .POJUPSJOH
    {
    asyncFun(context)
    }
    {
    getAuth(userID)
    }
    {
    logging(response)
    }
    {
    saveProfile(
    userID, profile
    )
    }

    View Slide

  154. ϚΠΫϩϑϨʔϜϫʔΫͷࢥ૝
    w ,UPS͕࠾༻͍ͯ͠ΔϚΠΫϩϑϨʔϜϫʔΫͳઃܭࢥ૝Λ঺հ
    w ,UPSຊମࣗମ͸8FC"QQ'SBNFXPSLͱͯ͠ඞཁ࠷௿ݶͷ

    ػೳ͔࣮͠૷͍ͯ͠ͳ͍ͨΊɺΞϓϦέʔγϣϯ։ൃऀ͕

    খ͘͞ߴ଎ʹΞϓϦέʔγϣϯΛ։ൃ͍ͯ͘͠ద͍ͯ͠Δ

    View Slide

  155. ϓϥάΠϯػߏͱύΠϓϥΠϯػߏ
    w ,UPSͷϝΠϯͷઃܭͰ͋Δ

    'FBUVSFʹΑΔϓϥάΠϯػߏͱύΠϓϥΠϯػߏΛ঺հ
    w ΞϓϦέʔγϣϯ։ൃऀʹඞཁͳػೳʹԠͯ͡ॊೈʹ

    ύΠϓϥΠϯΛߏ੒ΛͰ͖ΔΑ͏ͳ"1*Λఏڙ͍ͯ͠Δ

    View Slide

  156. KtorͱඇಉظॲཧύΠϓϥΠϯ
    w ,UPSͷඇಉظॲཧύΠϓϥΠϯ্ͰதஅॲཧΛ։࢝ͨ͠Γ

    ผεϨουͰಈ࡞͢ΔΑ͏ͳίϧʔνϯΛ։࢝ͨ͠ͱ͖ʹ

    ύΠϓϥΠϯͷ֤ϑΣΠζ͕ͲͷΑ͏ʹ࣮ߦ͞ΕΔ͔Λ঺հ
    w QSPFFEϝιουͳͲɺΑΓޮ཰తʹॲཧΛ࣮ߦ͞ΕΔͨΊͷ

    "1*͕,UPS͔Βఏڙ͞Ε͍ͯΔ

    View Slide

  157. Coroutinesͷ௿ϨϕϧAPI
    w ίϧʔνϯͰߴ͍ύϑΥʔϚϯεͳͲΛٻΊΔࡍʹ͸

    ॏཁʹͳͬͯ͘ΔΑ͏ͳ௿Ϩϕϧͷ"1*Λ঺հ
    w $POUJOVBUJPOTVTQFOEؔ਺ͷࣗಈมܗ
    w TUBSU$PSPVUJOF

    TUBSU$PSPVUJOF6OJOUFSDFQUFE0S3FUVSO
    w TVTQFOE$PSPVUJOF6OJOUFSDFQUFE0S3FUVSO

    View Slide

  158. KtorΛCoroutinesͰඥղ͘
    w ඇಉظॲཧύΠϓϥΠϯͰͷύϑΥʔϚϯεΛ

    ͋͛ΔͨΊʹ಺෦తʹίϧʔνϯͷ௿Ϩϕϧ"1*Λ׆༻ͨ͠

    ༷ʑͳςΫχοΫΛ঺հ
    w ,UPSΛ࢖Θͳ͍ΞϓϦέʔγϣϯ΍࡞ΔࡍͰ΋

    େྔͷίϧʔνϯΛ࢖ͬͯߴ͍ύϑΥʔϚϯεΛ

    ٻΊΒΕΔΑ͏ͳঢ়گͰ͸ࢀߟʹͳΔΑ͏ͳ࣮૷͕ଘࡏ

    View Slide