zio/zio2

java callback 을 ZIO 로 바꾸기

wefree 2022. 7. 17. 17:04

문제

https://wefree.tistory.com/199 에서는 java callback 를 scala Future 로 바꾸었다.

이번에는 ZIO.asyncZIO() 를 이용해 ZIO 로 변경해 보자.

https://wefree.tistory.com/199 와 동일하게  java Async Http Client 의 callback 을 살펴보자.

 

    val asyncHttpClient = org.asynchttpclient.Dsl.asyncHttpClient()
    val listenableFuture =
      asyncHttpClient.prepareGet("https://api.agify.io/?name=meelad").execute()

    val listener = new Runnable {
      override def run(): Unit = {
        val body: String =
          listenableFuture.get().getResponseBody(scala.io.Codec.UTF8.charSet)
        println(body)
      }
    }

    listenableFuture.addListener(listener, null)
    Thread.sleep(3000)
    asyncHttpClient.close()

 

코드

import org.asynchttpclient.AsyncHttpClient
import zio._

object ZioApp extends zio.ZIOAppDefault {
  val asyncHttpClient: ZIO[Scope, Throwable, AsyncHttpClient] =
    ZIO.acquireRelease(
      ZIO.attempt(org.asynchttpclient.Dsl.asyncHttpClient())
    )(x => ZIO.attempt(x.close()).ignore)

  val response: ZIO[Scope, Throwable, String] = ZIO.asyncZIO { cb =>
    val listenableFuture = asyncHttpClient.map(
      _.prepareGet("https://api.agify.io/?name=meelad").execute()
    )

    listenableFuture.map { lf =>
      lf.addListener(
        () => {
          val body: String =
            lf.get().getResponseBody(scala.io.Codec.UTF8.charSet)
          cb(ZIO.succeed(body))
        },
        null
      )
    }
  }

  def run = for {
    r <- response
    _ <- Console.printLine(r)
  } yield ()
}

 

설명

ZIO.asyncZIO() 코드를 살펴보면,  https://wefree.tistory.com/199 와 비슷하게 내부적으로 ZIO Promise 를 사용한 것을 알 수 있다.