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

WebFluxでコルーチン #m3kt

WebFluxでコルーチン #m3kt

どこでもKotlin #4 ( https://m3-engineer.connpass.com/event/70561/ )で発表したスライドです。

14c9795d267f5b85abb98ca5e8780646?s=128

Taro Nagasawa

November 27, 2017
Tweet

Transcript

  1. WebFluxでコルーチン 2017-11-22 どこでもKotlin #4 長澤太郎 @ngsw_taro

  2. 自己紹介 • 長澤 太郎(たろーって呼んでね) • @ngsw_taro • エムスリー株式会社 • ディズニーが大好き!

  3. 従来のスタイル @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    String { val itemA = demoService.getItemA() val itemB = demoService.getItemB() val itemC = demoService.getItemC(itemA, itemB) return itemC.answer } }
  4. 従来のスタイル @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    String { val itemA = demoService.getItemA() val itemB = demoService.getItemB() val itemC = demoService.getItemC(itemA, itemB) return itemC.answer } }
  5. 従来のスタイル @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    String { val itemA = demoService.getItemA() val itemB = demoService.getItemB() val itemC = demoService.getItemC(itemA, itemB) return itemC.answer } }
  6. 従来のスタイル @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    String { val itemA = demoService.getItemA() val itemB = demoService.getItemB() val itemC = demoService.getItemC(itemA, itemB) return itemC.answer } }
  7. 従来のスタイル @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    String { val itemA = demoService.getItemA() val itemB = demoService.getItemB() val itemC = demoService.getItemC(itemA, itemB) return itemC.answer } }
  8. 従来のスタイル @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    String { val itemA = demoService.getItemA() val itemB = demoService.getItemB() val itemC = demoService.getItemC(itemA, itemB) return itemC.answer } }
  9. WebFlux @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    Mono<String> = Mono.zip( demoService.getMonoA(), demoService.getMonoB() ) .flatMap { demoService.getMonoC(it.t1, it.t2) } .map { it.answer } } // dependencies compile('org.springframework.boot:spring-boot-starter-webflux')
  10. WebFlux @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    Mono<String> = Mono.zip( demoService.getMonoA(), demoService.getMonoB() ) .flatMap { demoService.getMonoC(it.t1, it.t2) } .map { it.answer } } // dependencies compile('org.springframework.boot:spring-boot-starter-webflux')
  11. @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono<String>

    = Mono.zip( demoService.getMonoA(), demoService.getMonoB() ) .flatMap { demoService.getMonoC(it.t1, it.t2) } .map { it.answer } } WebFlux // dependencies compile('org.springframework.boot:spring-boot-starter-webflux')
  12. @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono<String>

    = Mono.zip( demoService.getMonoA(), demoService.getMonoB() ) .flatMap { demoService.getMonoC(it.t1, it.t2) } .map { it.answer } } WebFlux // dependencies compile('org.springframework.boot:spring-boot-starter-webflux')
  13. @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono<String>

    = Mono.zip( demoService.getMonoA(), demoService.getMonoB() ) .flatMap { demoService.getMonoC(it.t1, it.t2) } .map { it.answer } } WebFlux // dependencies compile('org.springframework.boot:spring-boot-starter-webflux')
  14. @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono<String>

    = Mono.zip( demoService.getMonoA(), demoService.getMonoB() ) .flatMap { demoService.getMonoC(it.t1, it.t2) } .map { it.answer } } WebFlux // dependencies compile('org.springframework.boot:spring-boot-starter-webflux')
  15. Reactorでコルーチン @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    Mono<String> = mono { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } c.await().answer } } // dependencies compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' compile 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor:0.19.3'
  16. Reactorでコルーチン @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    Mono<String> = mono { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } c.await().answer } } // dependencies compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' compile 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor:0.19.3'
  17. Reactorでコルーチン @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    Mono<String> = mono { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } c.await().answer } } // dependencies compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' compile 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor:0.19.3'
  18. Reactorでコルーチン @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    Mono<String> = mono { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } c.await().answer } } // dependencies compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' compile 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor:0.19.3'
  19. Reactorでコルーチン @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    Mono<String> = mono { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } c.await().answer } } // dependencies compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' compile 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor:0.19.3'
  20. Channelで遊ぶ @RestController class DemoController { private val ch = Channel<String>()

    @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }
  21. Channelで遊ぶ @RestController class DemoController { private val ch = Channel<String>()

    @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }
  22. Channelで遊ぶ @RestController class DemoController { private val ch = Channel<String>()

    @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }
  23. Channelで遊ぶ @RestController class DemoController { private val ch = Channel<String>()

    @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }
  24. Channelで遊ぶ @RestController class DemoController { private val ch = Channel<String>()

    @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }
  25. Channelで遊ぶ @RestController class DemoController { private val ch = Channel<String>()

    @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }
  26. Channelで遊ぶ @RestController class DemoController { private val ch = Channel<String>()

    @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }
  27. Channelで遊ぶ @RestController class DemoController { private val ch = Channel<String>()

    @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }
  28. Channelで遊ぶ @RestController class DemoController { private val ch = Channel<String>()

    @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }
  29. None
  30. None
  31. ハンドラがサスペンド @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") suspend fun

    handle():String { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } return c.await().answer } } // dependencies compile 'org.springframework.kotlin:spring-webflux-kotlin-coroutine:0.3.1'
  32. ハンドラがサスペンド @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") suspend fun

    handle():String { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } return c.await().answer } } // dependencies compile 'org.springframework.kotlin:spring-webflux-kotlin-coroutine:0.3.1'
  33. Reactorでコルーチン @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle():

    Mono<String> = mono { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } c.await().answer } } // dependencies compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' compile 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor:0.19.3'
  34. まとめ • WebFluxはノンブロッキングでいいね! • ReactorはFutureやストリームみたいなやつを簡単に扱うこと ができるよ! • コルーチンは素直に非同期処理を書き下せていいね!