Skip to content
Snippets Groups Projects
Commit 319cc296 authored by Jens Nolte's avatar Jens Nolte
Browse files

Implement MonadAwait for STM (as an experiment)

parent decb1e80
No related branches found
No related tags found
Loading
...@@ -63,7 +63,7 @@ import GHC.IO (unsafeDupablePerformIO) ...@@ -63,7 +63,7 @@ import GHC.IO (unsafeDupablePerformIO)
import Quasar.Prelude import Quasar.Prelude
class (MonadCatch m, MonadFail m, MonadPlus m, MonadFix m) => MonadAwait m where class (MonadCatch m, MonadPlus m, MonadFix m) => MonadAwait m where
-- | Wait until an awaitable is completed and then return it's value (or throw an exception). -- | Wait until an awaitable is completed and then return it's value (or throw an exception).
await :: IsAwaitable r a => a -> m r await :: IsAwaitable r a => a -> m r
...@@ -88,6 +88,15 @@ instance MonadAwait IO where ...@@ -88,6 +88,15 @@ instance MonadAwait IO where
\BlockedIndefinitelyOnSTM -> throwM BlockedIndefinitelyOnAwait \BlockedIndefinitelyOnSTM -> throwM BlockedIndefinitelyOnAwait
unsafeAwaitSTM = atomically unsafeAwaitSTM = atomically
-- | Experimental instance for `STM`. Using `await` in STM circumvents awaitable caching mechanics, so this only
-- exists as a test to estimate the usefulness of caching awaitables against the usefulness of awaiting in STM.
instance MonadAwait STM where
await awaitable =
runQueryT id (runAwaitable awaitable)
`catch`
\BlockedIndefinitelyOnSTM -> throwM BlockedIndefinitelyOnAwait
unsafeAwaitSTM = id
instance MonadAwait m => MonadAwait (ReaderT a m) where instance MonadAwait m => MonadAwait (ReaderT a m) where
await = lift . await await = lift . await
unsafeAwaitSTM = lift . unsafeAwaitSTM unsafeAwaitSTM = lift . unsafeAwaitSTM
...@@ -231,7 +240,7 @@ awaitableFromSTM :: forall m a. MonadIO m => STM a -> m (Awaitable a) ...@@ -231,7 +240,7 @@ awaitableFromSTM :: forall m a. MonadIO m => STM a -> m (Awaitable a)
awaitableFromSTM transaction = cacheAwaitableUnlessPrimitive (unsafeAwaitSTM transaction :: Awaitable a) awaitableFromSTM transaction = cacheAwaitableUnlessPrimitive (unsafeAwaitSTM transaction :: Awaitable a)
instance {-# OVERLAPS #-} (MonadCatch m, MonadFail m, MonadPlus m, MonadFix m) => MonadAwait (ReaderT (QueryFn m) m) where instance {-# OVERLAPS #-} (MonadCatch m, MonadPlus m, MonadFix m) => MonadAwait (ReaderT (QueryFn m) m) where
await = runAwaitable await = runAwaitable
unsafeAwaitSTM transaction = do unsafeAwaitSTM transaction = do
QueryFn querySTMFn <- ask QueryFn querySTMFn <- ask
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment