zio/zio2
Ref vs Ref.Synchronized
wefree
2022. 12. 9. 19:30
Ref 와 Ref.Synchronized 의 차이는 무엇일까?
Ref
update function may be run more than once
import zio._
object RefApp extends zio.ZIOAppDefault {
def demo: UIO[Unit] = {
def task(id: Int, ref: Ref[Int]): UIO[Unit] =
ref.modify(prev => (println(s"Task $id updating ref at $prev"), id))
for {
ref <- Ref.make(0)
_ <- ZIO.collectAllParDiscard((1 to 5).toList.map(i => task(i, ref)))
} yield ()
}
override def run: ZIO[Any with ZIOAppArgs with Scope, Any, Any] = demo
}
실행 결과
lock 획득을 위해 retry 가 내부적으로 일어나 4번 이상 수행되었다.
Task1 --> Task5 --> Task3 --> Task2 --> Task4 순으로 ref state 를 업데이트 했다.
Task 1 updating ref at 0
Task 3 updating ref at 0
Task 5 updating ref at 0
Task 4 updating ref at 0
Task 5 updating ref at 1
Task 3 updating ref at 1
Task 3 updating ref at 5
Task 2 updating ref at 0
Task 4 updating ref at 1
Task 2 updating ref at 3
Task 4 updating ref at 3
Task 4 updating ref at 2
Ref.Synchronized
import zio._
object RefSynchronizedApp extends zio.ZIOAppDefault {
def demo: UIO[Unit] = {
def task(id: Int, ref: Ref[Int]): UIO[Unit] =
ref.modify(prev => (println(s"Task $id updating ref at $prev"), id))
for {
ref <- Ref.Synchronized.make(0)
_ <- ZIO.collectAllParDiscard((1 to 5).toList.map(i => task(i, ref)))
} yield ()
}
override def run: ZIO[Any with ZIOAppArgs with Scope, Any, Any] = demo
}
실행 결과
정확히 5번 수행된다.
Task 3 updating ref at 0
Task 5 updating ref at 3
Task 2 updating ref at 5
Task 4 updating ref at 2
Task 1 updating ref at 4