Преобразование типов, получая ZManaged от ZIO (Scala) - PullRequest
0 голосов
/ 23 апреля 2020

Мне нужна помощь для преобразования значения типа ZIO [WsConfig, Throwable, A] в ZManaged [A] Есть следующий код (я могу встроить его в IDEA, никаких ошибок, связанных с типами, ни у кого нет), но у меня есть ??? только на месте.

    def poolCache(implicit tag: Tagged[UcpZLayer.Service]): ZLayer[ZenvLogConfCache_, Throwable, UcpZLayer] = {

      val zm: ZIO[WsConfig, Throwable, ZManaged[Any, Throwable, UcpZLayer.Service]] =
        for {
          conf <- ZIO.environment[WsConfig]
          cpool <- Ref.make(new OraConnectionPool(conf.dbconf, conf.ucpconf))
          acquire = ZIO(new poolCache(cpool))
          release: (UcpZLayer.Service => zio.ZIO[Any,Nothing,Any]) = (pc: UcpZLayer.Service) => pc.closeAll
          zm: ZManaged[Any, Throwable, UcpZLayer.Service] = ZManaged.make(acquire)(release)
        } yield zm

      val managedConnPool: ZManaged[Any, Throwable, UcpZLayer.Service] = ???

      ZLayer.fromManaged(managedConnPool)
    }

Может быть полезным - этот метод poolCache, который я использую для создания ZLayer

object EnvContainer {
  type IncConnSrvBind = akka.stream.scaladsl.Source[IncomingConnection, Future[ServerBinding]]

  type ZEnvLog = ZEnv with Logging
  type ZEnvLogCache =  ZEnvLog with CacheManager
  type ZenvLogConfCache_ =  ZEnvLogCache with config.Config[WsConfig]
  type ZEnvConfLogCache =  ZEnvLogCache with config.Config[WsConfig] with UcpZLayer

   val envLog: ZLayer[Console with Clock, Nothing, Logging]   =
    Logging.console((_, logEntry) =>
      logEntry
    )

  val ZEnvLogLayer:  ZLayer[ZEnv, Nothing, ZEnvLog] = ZEnv.live ++ envLog

  val ZEnvLogCacheLayer: ZLayer[ZEnv, Nothing, ZEnvLogCache] =
    ZEnv.live ++ envLog ++ CacheManager.refCache

  def ZEnvConfLogCacheLayer(confFileName: String): ZLayer[ZEnv, Throwable, ZEnvConfLogCache] = {
    val confLayer = configLayer(confFileName)
    val combEnvWithoutPool = ZEnv.live ++ envLog ++ confLayer ++ CacheManager.refCache
    combEnvWithoutPool ++ (combEnvWithoutPool >>> Ucp.UcpZLayer.poolCache)
  }

}

Я комбинирую любые ZLayers (с confLayer) по горизонтали с ++ и перейти в poolCache с >>>.

Ответы [ 2 ]

1 голос
/ 23 апреля 2020

Я бы предложил сделать что-то вроде этого:

    def poolCache(implicit tag: Tagged[UcpZLayer.Service]): ZLayer[ZenvLogConfCache_, Throwable, UcpZLayer] =
      (for {
        // Use a Managed directly when access then environment
        // `access` will remove the `Has` wrapping.
        conf  <- ZManaged.access[Config[WsConfig]](_.get)

        // Convert the effect into a no-release managed
        cpool <- Ref.make(new OraConnectionPool(conf.dbconf, conf.ucpconf)).toManaged_

        // Create the managed
        zm    <- ZManaged.make(ZIO(new poolCache(cpool)))(_.closeAll)
      } yield zm).toLayer // Convert a `Managed` to `ZLayer` directly
0 голосов
/ 23 апреля 2020

paulpdaniels

Большое спасибо. Когда я пытаюсь использовать ваше прямое предложение, оно вызывает ошибку типа:

    Required: zio.ZLayer[ZenvLogConfCache_, Throwable, zio.Has[Service]]
    Found:    zio.ZLayer[R with Config[WsConfig], Throwable, zio.Has[poolCache]]

Я переписываю его в следующей форме

      def poolCache(implicit tag: Tagged[UcpZLayer.Service]): ZLayer[ZenvLogConfCache_, Throwable, Has[UcpZLayer.Service]] = {
        val zm: ZManaged[Config[WsConfig], Throwable, poolCache] =
          for {
            // Use a Managed directly when access then environment
            conf <- ZManaged.access[Config[WsConfig]](_.get)
            // Convert the effect into a no-release managed
            cpool <- Ref.make(new OraConnectionPool(conf.dbconf, conf.ucpconf)).toManaged_
            // Create the managed
            zm <- ZManaged.make(ZIO(new poolCache(cpool)))(_.closeAll)
          } yield zm
        zm.toLayer // Convert a `Managed` to `ZLayer` directly
      }

, теперь я могу построить без каких-либо ошибок. Еще раз спасибо.

...