-
Ref vs Ref.Synchronizedzio/zio2 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
'zio > zio2' 카테고리의 다른 글
Fiber (0) 2022.11.23 Error Models (0) 2022.11.20 Option 처리하기 (0) 2022.11.20 ZLayer 를 이용한 dependency injection (0) 2022.07.27 java callback 을 ZIO 로 바꾸기 (0) 2022.07.17