@@ -1,8 +1,7 @@
1{-# LANGUAGE FlexibleContexts #-}
1{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
2+{-# LANGUAGE FlexibleInstances #-}
3{-# LANGUAGE StandaloneDeriving #-}
3{-# LANGUAGE StandaloneDeriving #-}
4{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5−{-# LANGUAGE UndecidableInstances #-}
8-- Module : Asyncly.Threads
7-- Module : Asyncly.Threads
@@ -19,11 +18,12 @@ module Asyncly.RunAsync
23− , waitRecord_
23+ , runAsyclyRecorded
24 , waitRecord
24 , waitRecord
@@ -34,7 +34,7 @@ import Control.Monad.Catch (MonadCatch, MonadThrow, throwM, tr
34import Control.Monad.IO.Class (MonadIO (..))
34import Control.Monad.IO.Class (MonadIO (..))
35import Control.Monad.Trans.Class (MonadTrans (lift))
35import Control.Monad.Trans.Class (MonadTrans (lift))
36import Control.Monad.Trans.Control (MonadBaseControl)
36import Control.Monad.Trans.Control (MonadBaseControl)
37−import Control.Monad.State (StateT, runStateT)
37+import Control.Monad.State (StateT(..), runStateT)
38import Control.Monad.Trans.Class (MonadTrans (lift))
38import Control.Monad.Trans.Class (MonadTrans (lift))
39import Data.Atomics (atomicModifyIORefCAS)
39import Data.Atomics (atomicModifyIORefCAS)
40import Data.IORef (IORef, newIORef, readIORef)
40import Data.IORef (IORef, newIORef, readIORef)
@@ -53,14 +53,23 @@ import Asyncly.AsyncT
54newtype AsynclyT m a = AsynclyT { runAsynclyT :: AsyncT (StateT Context m) a }
54newtype AsynclyT m a = AsynclyT { runAsynclyT :: AsyncT (StateT Context m) a }
56−deriving instance MonadAsync m => Functor (AsynclyT m)
56+deriving instance Monad m => Functor (AsynclyT m)
57−deriving instance MonadAsync m => Applicative (AsynclyT m)
57+deriving instance Monad m => Applicative (AsynclyT m)
58−deriving instance MonadAsync m => Alternative (AsynclyT m)
58+deriving instance Monad m => Alternative (AsynclyT m)
59−deriving instance MonadAsync m => Monad (AsynclyT m)
59+deriving instance Monad m => Monad (AsynclyT m)
60−deriving instance MonadAsync m => MonadIO (AsynclyT m)
60+deriving instance MonadIO m => MonadIO (AsynclyT m)
61instance MonadTrans (AsynclyT) where
61instance MonadTrans (AsynclyT) where
62 lift mx = AsynclyT $ AsyncT $ \s k -> lift mx >>= (\a -> (k a Nothing))
62 lift mx = AsynclyT $ AsyncT $ \s k -> lift mx >>= (\a -> (k a Nothing))
64+instance (Monad m, MonadRecorder m)
65+ => MonadRecorder (StateT Context m) where
66+ getJournal = lift getJournal
67+ putJournal = lift . putJournal
70+deriving instance (Monad m, MonadRecorder m)
71+ => MonadRecorder (AsynclyT m)
64------------------------------------------------------------------------------
73------------------------------------------------------------------------------
65-- Running the monad
74-- Running the monad
66------------------------------------------------------------------------------
75------------------------------------------------------------------------------
@@ -124,23 +133,23 @@ threads :: MonadAsync m => Int -> AsynclyT m a -> AsynclyT m a
124threads n action = AsynclyT $ AsyncT $ \stp yld ->
133threads n action = AsynclyT $ AsyncT $ \stp yld ->
125 threadCtl n ((runAsyncT $ runAsynclyT action) stp yld)
134 threadCtl n ((runAsyncT $ runAsynclyT action) stp yld)
128------------------------------------------------------------------------------
136------------------------------------------------------------------------------
129-- Logging
137-- Logging
130------------------------------------------------------------------------------
138------------------------------------------------------------------------------
132-- | Compose a computation using previously captured logs
140-- | Compose a computation using previously captured logs
133playRecording :: (MonadAsync m, MonadRecorder m)
141playRecording :: (MonadAsync m, MonadRecorder m)
134− => AsyncT m a -> Recording -> AsyncT m a
142+ => AsynclyT m a -> Recording -> AsynclyT m a
135playRecording m recording = play recording >> m
143playRecording m recording = play recording >> m
137-- | Resume an 'AsyncT' computation using previously recorded logs. The
145-- | Resume an 'AsyncT' computation using previously recorded logs. The
138-- recording consists of a list of journals one for each thread in the
146-- recording consists of a list of journals one for each thread in the
139-- computation.
147-- computation.
140playRecordings :: (MonadAsync m, MonadRecorder m)
148playRecordings :: (MonadAsync m, MonadRecorder m)
141− => AsyncT m a -> [Recording] -> AsyncT m a
149+ => AsynclyT m a -> [Recording] -> AsynclyT m a
142playRecordings m logs = each logs >>= playRecording m
150playRecordings m logs = each logs >>= playRecording m
144-- | Run an 'AsyncT' computation with recording enabled, wait for it to finish
153-- | Run an 'AsyncT' computation with recording enabled, wait for it to finish
145-- returning results for completed threads and recordings for paused threads.
154-- returning results for completed threads and recordings for paused threads.
146waitRecord :: (MonadAsync m, MonadCatch m)
155waitRecord :: (MonadAsync m, MonadCatch m)
@@ -156,12 +165,11 @@ waitRecord m = do
156-- | Run an 'AsyncT' computation with recording enabled, wait for it to finish
165-- | Run an 'AsyncT' computation with recording enabled, wait for it to finish
157-- and discard the results and return the recordings for paused threads, if
166-- and discard the results and return the recordings for paused threads, if
159−waitRecord_ :: (MonadAsync m, MonadCatch m)
168+runAsynclyRecorded :: (MonadAsync m, MonadCatch m)
160− => AsyncT (RecorderT m) a -> m [Recording]
169+ => AsynclyT (RecorderT m) a -> m [Recording]
161−waitRecord_ m = do
170+runAsynclyRecorded m = do
162 lref <- liftIO $ newIORef []
171 lref <- liftIO $ newIORef []
163 runRecorderT blank (waitAsync (const (return Nothing)) (Just lref) m)
172 runRecorderT blank (waitAsync (const (return Nothing)) (Just lref) m)
164 logs <- liftIO $ readIORef lref
173 logs <- liftIO $ readIORef lref
165 return logs
174 return logs