资源管理

本章节探讨使用 ZIO 来管理资源的通常的方法。

ZIO的资源管理功能包含了同步,异步,并发和其他 effect 类型,即使在应用程序出现故障,中断或缺陷的情况下,也能提供有力的保证。

Finalizing

通过  ZIO#ensuring  方法,ZIO 提供了类似 try / finally 的机制。

类似于 try / finally 一样, ensuring 函数可确保“终结器(finalizer)”将在一个 effect 开始执行然后终止(无论出于何种原因)后开始执行。

val finalizer = 
  UIO.effectTotal(println("Finalizing!"))
// finalizer: UIO[Unit] = zio.ZIO$EffectTotal@4ffbaf7e

val finalized: IO[String, Unit] = 
  IO.fail("Failed!").ensuring(finalizer)
// finalized: IO[String, Unit] = zio.ZIO$CheckInterrupt@4f16a3db

终结器是不允许失败的,这意味着它必须在内部处理所有的错误。

和 try / finally 一样,终结器可以嵌套,并且任何来自内部终结器的错误不会影响到它的外部终结器。嵌套终结器的执行顺序是反向,并且线性的(不是并行的)。

和 try / finally 不同的是,ensuring 可以工作于所有的 effect 类型,包括异步和并发 effect。

Bracket

通常 try / finally 被用于安全地获取和释放资源,例如一个新的 socket 的连接或一个文件的打开:

val handle = openFile(name)

try {
  processFile(handle)
} finally closeFile(handle)

ZIO 将这种通用模式封装在 ZIO#bracket 中,它允许您自动一个acquire effect 用于获取资源;一个 release effect 用于释放它;和一个 use effect 用于使用资源。

运行时系统将保证 release effect 的执行,哪怕存在错误或中断。

val groupedFileData: IO[IOException, Unit] = 
  openFile("data.json").bracket(closeFile(_)) { file =>
    for {
      data    <- decodeData(file)
      grouped <- groupData(data)
    } yield grouped
  }

和 ensuring 一样,brackets 具有语意成分,所以如果一个 bracket 嵌套在另一个 bracket 里面,那么当外部 bracket 获取资源的时候,也就意味着这个外部 bracket’s 的 release 函数也将会被执行,无论它的内嵌 bracket 的释放失败与否。

Next Steps

如果您对资源处理感到满意,那么下一步就是学习基本并发处理

Leave a Reply
Your email address will not be published.
*
*

BACK TO TOP