概要
前回の記事では、
ZIOのScopeについて簡単に共有しました。
今回の記事では、より実績的なScopeの有効期間の制御例について共有させていただきます。
Scopeの動的な有効期間について
Scope
の有効期間は動的です。
Scope
を必要とするZIOエフェクトがある場合、それをflatMap
して新しいエフェクトを作成できます。
新しいZIOエフェクトは元のScope
の有効期間を延長します。
したがって、Scopeを閉じない限り、リソースは解放されず、Scope
を閉じるまでリソースはどんどん大きくなります。
Scopeが延長される例
以下のサンプルプログラムは、使い終わったら削除されるような一時ファイルtmpFile
をScope
によって取り扱ったものです。
checkFileExists
でファイルが存在するかどうか(Scope
が閉じられたかどうか)が確認できるようになっています。
import zio.*
import java.io.File
object Main extends ZIOAppDefault:
val PathToFile = "/tmp/tmp.txt"
def tmpFile: ZIO[Scope, Throwable, Unit] = for {
file <- ZIO.acquireRelease(
ZIO.attemptBlocking {
val file = new File(PathToFile)
file.createNewFile()
file
}
)(deleteFile)
} yield ()
def deleteFile(file: File): UIO[Unit] =
ZIO.attemptBlocking(file.delete()).orDie.unit
def checkFileExists: Task[Unit] = for {
exists <- ZIO.attemptBlocking(new File(PathToFile).exists())
_ <- Console.printLine(exists)
} yield ()
override def run: ZIO[ZIOAppArgs & Scope, Any, Any] =
for {
_ <- ZIO.debug("開始")
_ <- tmpFile
_ <- checkFileExists
_ <- ZIO.debug("終了")
_ <- checkFileExists
} yield ()
実行結果
開始
true
終了
true
プログラム終了後にファイルの存在を確認した結果
$ pwd
/tmp
$ ls | grep 'tmp.txt'
実行結果
およびls
コマンドの結果より、
一時ファイルは作られてからプログラム終了時まで存在し続けていたことが示唆されます。
Scope#scopedでScopeを閉じる
次にサンプルプログラムを改変して、以下のようにtmpFile
をZIO.scoped
で包むようにしてみます。
これによりtmpFile
のScope
が延長されないようになります。
override def run: ZIO[ZIOAppArgs & Scope, Any, Any] =
for {
_ <- ZIO.debug("開始")
_ <- ZIO.scoped(tmpFile)
_ <- checkFileExists
_ <- ZIO.debug("終了")
_ <- checkFileExists
} yield ()
実行結果
開始
false
終了
false
実行結果
よりZIO.scoped(tmpFile)
以降の処理ではファイルが存在しない(Scope
が閉じられた)ことが確認できます。