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
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
|
|
}
|