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

package nova.monadic_sfx.util
import monix.bio.Task
import monix.bio.UIO
import monix.catnap.MVar
/**
* Synchronization wrapper for a mutable object
*
* @param obj the mutable object
* @param lock lock for synchronization
*/
class SynchedObject[A](obj: A, lock: MLock) {
def modify(f: A => Task[Unit]): Task[Unit] =
lock.greenLight(f(obj))
def get: Task[A] = lock.greenLight(Task(obj))
}
object SynchedObject {
def apply[A](obj: A) =
MVar[Task]
.of(())
.map(m => new MLock(m))
.flatMap(lock => Task(new SynchedObject(obj, lock)))
}
final class MLock(mvar: MVar[Task, Unit]) {
def acquire: Task[Unit] =
mvar.take
def release: Task[Unit] =
mvar.put(())
def greenLight[A](fa: Task[A]): Task[A] =
for {
_ <- acquire
a <- fa.doOnCancel(
release.onErrorHandleWith(ex => UIO(println(ex.getMessage())))
)
_ <- release
} yield a
}