You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

44 lines
926 B

  1. package nova.monadic_sfx.util
  2. import monix.bio.Task
  3. import monix.bio.UIO
  4. import monix.catnap.MVar
  5. /**
  6. * Synchronization wrapper for a mutable object
  7. *
  8. * @param obj the mutable object
  9. * @param lock lock for synchronization
  10. */
  11. class SynchedObject[A](obj: A, lock: MLock) {
  12. def modify(f: A => Task[Unit]): Task[Unit] =
  13. lock.greenLight(f(obj))
  14. def get: Task[A] = lock.greenLight(Task(obj))
  15. }
  16. object SynchedObject {
  17. def apply[A](obj: A) =
  18. MVar[Task]
  19. .of(())
  20. .map(m => new MLock(m))
  21. .flatMap(lock => Task(new SynchedObject(obj, lock)))
  22. }
  23. final class MLock(mvar: MVar[Task, Unit]) {
  24. def acquire: Task[Unit] =
  25. mvar.take
  26. def release: Task[Unit] =
  27. mvar.put(())
  28. def greenLight[A](fa: Task[A]): Task[A] =
  29. for {
  30. _ <- acquire
  31. a <- fa.doOnCancel(
  32. release.onErrorHandleWith(ex => UIO(println(ex.getMessage())))
  33. )
  34. _ <- release
  35. } yield a
  36. }