概要
Scope型は、ZIOの安全で合成可能なリソース処理基盤です。
これは一つまたは複数のリソースのライフタイムを表します。リソースはスコープ内で使用され、スコープが閉じられるときに解放されます。
最初の例
Scope#make
を呼び出すとUIO[Scope.Closeable]
型の値を手に入れることができます。
Closeable
はScope
を継承したトレイトです。
Scope
はaddFinalizer
を呼び出すことにより、
ファイナライズ処理を追加することができます。
object Main extends ZIOAppDefault:
override def run: ZIO[ZIOAppArgs & Scope, Any, Any] =
for {
scope: Scope.Closeable <- Scope.make
_: Unit <- scope.addFinalizer(
for {
_ <- ZIO.debug("ファイナライズ処理")
} yield ()
)
_: Unit <- ZIO.debug("開始")
_: Unit <- scope.close(Exit.succeed(()))
_: Unit <- ZIO.debug("終了")
} yield ()
実行結果
開始
ファイナライズ処理
終了
ZIO#acquireRelease
ZIO#acquireRelease
を使うことによって、
リソースの取得と解放を1つのZIOエフェクトにまとめられ、リソース解放漏れのリスクを軽減できます。
acquireReleaseの使用例
object Main extends ZIOAppDefault:
def acquire(name: => String): ZIO[Any, IOException, Source] =
ZIO.attemptBlockingIO(Source.fromFile(name))
def release(source: => Source): ZIO[Any, Nothing, Unit] =
ZIO.succeedBlocking(source.close())
def source(name: => String): ZIO[Scope, IOException, Source] =
ZIO.acquireRelease(acquire(name))(release(_))
override def run: ZIO[ZIOAppArgs & Scope, Any, Any] =
for {
s: Source <- source("/Users/tobita/.gitignore_global")
lines: Iterator[String] <- ZIO.attemptBlockingIO(s.getLines())
_ <- Console.print(lines.mkString("\n"))
} yield ()
実行結果
.DS_Store
.idea
ZIO#scoped
ZIO#scoped
は、渡されたZIOエフェクトを新しいスコープ内で実行し、そのスコープを自動的に閉じる関数です。
object Main extends ZIOAppDefault:
def inScope: URIO[Scope, Unit] = for {
_ <- ZIO.addFinalizer(ZIO.debug("ファイナライズ処理"))
_ <- ZIO.debug("スコープ内の処理")
} yield ()
override def run: ZIO[ZIOAppArgs & Scope, Any, Any] =
for {
_ <- ZIO.debug("開始")
_ <- ZIO.scoped(inScope)
_ <- ZIO.debug("終了")
} yield ()
実行結果
開始
スコープ内の処理
ファイナライズ処理
終了