lifted-async 0.8.0.1 → 0.9.0
raw patch · 5 files changed
+87/−39 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Control.Concurrent.Async.Lifted: waitEither_ :: MonadBaseControl IO m => Async a -> Async b -> m ()
+ Control.Concurrent.Async.Lifted: waitEither_ :: MonadBase IO m => Async a -> Async b -> m ()
- Control.Concurrent.Async.Lifted.Safe: poll :: (MonadBaseControl IO m, Forall (Pure m)) => Async a -> m (Maybe (Either SomeException a))
+ Control.Concurrent.Async.Lifted.Safe: poll :: (MonadBase IO m, Forall (Pure m)) => Async a -> m (Maybe (Either SomeException a))
- Control.Concurrent.Async.Lifted.Safe: wait :: (MonadBaseControl IO m, Forall (Pure m)) => Async a -> m a
+ Control.Concurrent.Async.Lifted.Safe: wait :: (MonadBase IO m, Forall (Pure m)) => Async a -> m a
- Control.Concurrent.Async.Lifted.Safe: waitAny :: (MonadBaseControl IO m, Forall (Pure m)) => [Async a] -> m (Async a, a)
+ Control.Concurrent.Async.Lifted.Safe: waitAny :: (MonadBase IO m, Forall (Pure m)) => [Async a] -> m (Async a, a)
- Control.Concurrent.Async.Lifted.Safe: waitAnyCancel :: (MonadBaseControl IO m, Forall (Pure m)) => [Async a] -> m (Async a, a)
+ Control.Concurrent.Async.Lifted.Safe: waitAnyCancel :: (MonadBase IO m, Forall (Pure m)) => [Async a] -> m (Async a, a)
- Control.Concurrent.Async.Lifted.Safe: waitAnyCatch :: (MonadBaseControl IO m, Forall (Pure m)) => [Async a] -> m (Async a, Either SomeException a)
+ Control.Concurrent.Async.Lifted.Safe: waitAnyCatch :: (MonadBase IO m, Forall (Pure m)) => [Async a] -> m (Async a, Either SomeException a)
- Control.Concurrent.Async.Lifted.Safe: waitAnyCatchCancel :: (MonadBaseControl IO m, Forall (Pure m)) => [Async a] -> m (Async a, Either SomeException a)
+ Control.Concurrent.Async.Lifted.Safe: waitAnyCatchCancel :: (MonadBase IO m, Forall (Pure m)) => [Async a] -> m (Async a, Either SomeException a)
- Control.Concurrent.Async.Lifted.Safe: waitBoth :: (MonadBaseControl IO m, Forall (Pure m)) => Async a -> Async b -> m (a, b)
+ Control.Concurrent.Async.Lifted.Safe: waitBoth :: (MonadBase IO m, Forall (Pure m)) => Async a -> Async b -> m (a, b)
- Control.Concurrent.Async.Lifted.Safe: waitCatch :: (MonadBaseControl IO m, Forall (Pure m)) => Async a -> m (Either SomeException a)
+ Control.Concurrent.Async.Lifted.Safe: waitCatch :: (MonadBase IO m, Forall (Pure m)) => Async a -> m (Either SomeException a)
- Control.Concurrent.Async.Lifted.Safe: waitEither :: (MonadBaseControl IO m, Forall (Pure m)) => Async a -> Async b -> m (Either a b)
+ Control.Concurrent.Async.Lifted.Safe: waitEither :: (MonadBase IO m, Forall (Pure m)) => Async a -> Async b -> m (Either a b)
- Control.Concurrent.Async.Lifted.Safe: waitEitherCancel :: (MonadBaseControl IO m, Forall (Pure m)) => Async a -> Async b -> m (Either a b)
+ Control.Concurrent.Async.Lifted.Safe: waitEitherCancel :: (MonadBase IO m, Forall (Pure m)) => Async a -> Async b -> m (Either a b)
- Control.Concurrent.Async.Lifted.Safe: waitEitherCatch :: (MonadBaseControl IO m, Forall (Pure m)) => Async a -> Async b -> m (Either (Either SomeException a) (Either SomeException b))
+ Control.Concurrent.Async.Lifted.Safe: waitEitherCatch :: (MonadBase IO m, Forall (Pure m)) => Async a -> Async b -> m (Either (Either SomeException a) (Either SomeException b))
- Control.Concurrent.Async.Lifted.Safe: waitEitherCatchCancel :: (MonadBaseControl IO m, Forall (Pure m)) => Async a -> Async b -> m (Either (Either SomeException a) (Either SomeException b))
+ Control.Concurrent.Async.Lifted.Safe: waitEitherCatchCancel :: (MonadBase IO m, Forall (Pure m)) => Async a -> Async b -> m (Either (Either SomeException a) (Either SomeException b))
- Control.Concurrent.Async.Lifted.Safe: waitEither_ :: MonadBaseControl IO m => Async a -> Async b -> m ()
+ Control.Concurrent.Async.Lifted.Safe: waitEither_ :: MonadBase IO m => Async a -> Async b -> m ()
Files
- CHANGELOG.md +4/−0
- benchmarks/Benchmarks.hs +36/−1
- lifted-async.cabal +4/−3
- src/Control/Concurrent/Async/Lifted.hs +1/−1
- src/Control/Concurrent/Async/Lifted/Safe.hs +42/−34
CHANGELOG.md view
@@ -1,3 +1,7 @@+## v0.9.0 - 2016-05-22++* Leverage `StM m a ~ a` in the `Safe` module for faster `wait`/`poll`/`race`/`concurrently`+ ## v0.8.0.1 - 2015-01-17 * Relax upper bound for constraints
benchmarks/Benchmarks.hs view
@@ -1,40 +1,46 @@-{-# LANGUAGE BangPatterns #-} module Main where import Control.Exception (SomeException(..)) import Criterion.Main import qualified Control.Concurrent.Async as A import qualified Control.Concurrent.Async.Lifted as L+import qualified Control.Concurrent.Async.Lifted.Safe as LS main :: IO () main = defaultMain [ bgroup "async-wait" [ bench "async" $ whnfIO asyncWait_async , bench "lifted-async" $ whnfIO asyncWait_liftedAsync+ , bench "lifted-async-safe" $ whnfIO asyncWait_liftedAsyncSafe ] , bgroup "async-cancel-waitCatch" [ bench "async" $ whnfIO asyncCancelWaitCatch_async , bench "lifted-async" $ whnfIO asyncCancelWaitCatch_liftedAsync+ , bench "lifted-async-safe" $ whnfIO asyncCancelWaitCatch_liftedAsyncSafe ] , bgroup "waitAny" [ bench "async" $ whnfIO waitAny_async , bench "lifted-async" $ whnfIO waitAny_liftedAsync+ , bench "lifted-async-safe" $ whnfIO waitAny_liftedAsyncSafe ] , bgroup "race" [ bench "async" $ nfIO race_async , bench "lifted-async" $ nfIO race_liftedAsync+ , bench "lifted-async-safe" $ nfIO race_liftedAsyncSafe , bench "async (inlined)" $ nfIO race_async_inlined , bench "lifted-async (inlined)" $ nfIO race_liftedAsync_inlined ] , bgroup "concurrently" [ bench "async" $ nfIO concurrently_async , bench "lifted-async" $ nfIO concurrently_liftedAsync+ , bench "lifted-async-safe" $ nfIO concurrently_liftedAsyncSafe , bench "async (inlined)" $ nfIO concurrently_async_inlined , bench "lifted-async (inlined)" $ nfIO concurrently_liftedAsync_inlined ] , bgroup "mapConcurrently" [ bench "async" $ nfIO mapConcurrently_async , bench "lifted-async" $ nfIO mapConcurrently_liftedAsync+ , bench "lifted-async-safe" $ nfIO mapConcurrently_liftedAsyncSafe ] ] @@ -48,6 +54,11 @@ a <- L.async (return 1) L.wait a +asyncWait_liftedAsyncSafe :: IO Int+asyncWait_liftedAsyncSafe = do+ a <- LS.async (return 1)+ LS.wait a+ asyncCancelWaitCatch_async :: IO (Either SomeException Int) asyncCancelWaitCatch_async = do a <- A.async (return 1)@@ -60,6 +71,12 @@ L.cancel a L.waitCatch a +asyncCancelWaitCatch_liftedAsyncSafe :: IO (Either SomeException Int)+asyncCancelWaitCatch_liftedAsyncSafe = do+ a <- LS.async (return 1)+ LS.cancel a+ LS.waitCatch a+ waitAny_async :: IO Int waitAny_async = do as <- mapM (A.async . return) [1..10]@@ -72,6 +89,12 @@ (_, n) <- L.waitAny as return n +waitAny_liftedAsyncSafe :: IO Int+waitAny_liftedAsyncSafe = do+ as <- mapM (LS.async . return) [1..10]+ (_, n) <- LS.waitAny as+ return n+ race_async :: IO (Either Int Int) race_async = A.race (return 1) (return 2)@@ -80,6 +103,10 @@ race_liftedAsync = L.race (return 1) (return 2) +race_liftedAsyncSafe :: IO (Either Int Int)+race_liftedAsyncSafe =+ LS.race (return 1) (return 2)+ race_async_inlined :: IO (Either Int Int) race_async_inlined = A.withAsync (return 1) $ \a ->@@ -100,6 +127,10 @@ concurrently_liftedAsync = L.concurrently (return 1) (return 2) +concurrently_liftedAsyncSafe :: IO (Int, Int)+concurrently_liftedAsyncSafe =+ LS.concurrently (return 1) (return 2)+ concurrently_async_inlined :: IO (Int, Int) concurrently_async_inlined = A.withAsync (return 1) $ \a ->@@ -119,3 +150,7 @@ mapConcurrently_liftedAsync :: IO [Int] mapConcurrently_liftedAsync = L.mapConcurrently return [1..10]++mapConcurrently_liftedAsyncSafe :: IO [Int]+mapConcurrently_liftedAsyncSafe =+ LS.mapConcurrently return [1..10]
lifted-async.cabal view
@@ -1,5 +1,5 @@ name: lifted-async-version: 0.8.0.1+version: 0.9.0 synopsis: Run lifted IO operations asynchronously and wait for their results homepage: https://github.com/maoe/lifted-async bug-reports: https://github.com/maoe/lifted-async/issues@@ -12,7 +12,8 @@ build-type: Simple cabal-version: >= 1.8 tested-with:- GHC == 7.10.2+ GHC == 8.0.1+ , GHC == 7.10.2 , GHC == 7.8.4 , GHC == 7.6.3 @@ -114,5 +115,5 @@ source-repository this type: git- tag: v0.8.0.1+ tag: v0.9.0 location: https://github.com/maoe/lifted-async.git
src/Control/Concurrent/Async/Lifted.hs view
@@ -305,7 +305,7 @@ -- NOTE: This function discards the monadic effects besides IO in the forked -- computation. waitEither_- :: MonadBaseControl IO m+ :: MonadBase IO m => Async a -> Async b -> m ()
src/Control/Concurrent/Async/Lifted/Safe.hs view
@@ -50,7 +50,7 @@ -- ** Waiting for multiple 'Async's , waitAny, waitAnyCatch, waitAnyCancel, waitAnyCatchCancel , waitEither, waitEitherCatch, waitEitherCancel, waitEitherCatchCancel- , Unsafe.waitEither_+ , waitEither_ , waitBoth #if MIN_VERSION_async(2, 1, 0)@@ -192,25 +192,25 @@ -- | Generalized version of 'A.wait'. wait- :: forall m a. (MonadBaseControl IO m, Forall (Pure m))+ :: forall m a. (MonadBase IO m, Forall (Pure m)) => Async a -> m a-wait = Unsafe.wait+wait = liftBase . A.wait \\ (inst :: Forall (Pure m) :- Pure m a) -- | Generalized version of 'A.poll'. poll- :: forall m a. (MonadBaseControl IO m, Forall (Pure m))+ :: forall m a. (MonadBase IO m, Forall (Pure m)) => Async a -> m (Maybe (Either SomeException a))-poll = Unsafe.poll+poll = liftBase . A.poll \\ (inst :: Forall (Pure m) :- Pure m a) -- | Generalized version of 'A.waitCatch'. waitCatch- :: forall m a. (MonadBaseControl IO m, Forall (Pure m))+ :: forall m a. (MonadBase IO m, Forall (Pure m)) => Async a -> m (Either SomeException a)-waitCatch = Unsafe.waitCatch+waitCatch = liftBase . A.waitCatch \\ (inst :: Forall (Pure m) :- Pure m a) -- | Generalized version of 'A.cancel'.@@ -223,82 +223,86 @@ -- | Generalized version of 'A.waitAny'. waitAny- :: forall m a. (MonadBaseControl IO m, Forall (Pure m))+ :: forall m a. (MonadBase IO m, Forall (Pure m)) => [Async a] -> m (Async a, a)-waitAny = Unsafe.waitAny+waitAny = liftBase . A.waitAny \\ (inst :: Forall (Pure m) :- Pure m a) -- | Generalized version of 'A.waitAnyCatch'. waitAnyCatch- :: forall m a. (MonadBaseControl IO m, Forall (Pure m))+ :: forall m a. (MonadBase IO m, Forall (Pure m)) => [Async a] -> m (Async a, Either SomeException a)-waitAnyCatch = Unsafe.waitAnyCatch+waitAnyCatch = liftBase . A.waitAnyCatch \\ (inst :: Forall (Pure m) :- Pure m a) -- | Generalized version of 'A.waitAnyCancel'. waitAnyCancel- :: forall m a. (MonadBaseControl IO m, Forall (Pure m))+ :: forall m a. (MonadBase IO m, Forall (Pure m)) => [Async a] -> m (Async a, a)-waitAnyCancel = Unsafe.waitAnyCancel+waitAnyCancel = liftBase . A.waitAnyCancel \\ (inst :: Forall (Pure m) :- Pure m a) -- | Generalized version of 'A.waitAnyCatchCancel'. waitAnyCatchCancel- :: forall m a. (MonadBaseControl IO m, Forall (Pure m))+ :: forall m a. (MonadBase IO m, Forall (Pure m)) => [Async a] -> m (Async a, Either SomeException a)-waitAnyCatchCancel = Unsafe.waitAnyCatchCancel+waitAnyCatchCancel = liftBase . A.waitAnyCatchCancel \\ (inst :: Forall (Pure m) :- Pure m a) -- | Generalized version of 'A.waitEither'. waitEither- :: forall m a b. (MonadBaseControl IO m, Forall (Pure m))+ :: forall m a b. (MonadBase IO m, Forall (Pure m)) => Async a -> Async b -> m (Either a b)-waitEither = Unsafe.waitEither+waitEither = (liftBase .) . A.waitEither \\ (inst :: Forall (Pure m) :- Pure m a) \\ (inst :: Forall (Pure m) :- Pure m b) -- | Generalized version of 'A.waitEitherCatch'. waitEitherCatch- :: forall m a b. (MonadBaseControl IO m, Forall (Pure m))+ :: forall m a b. (MonadBase IO m, Forall (Pure m)) => Async a -> Async b -> m (Either (Either SomeException a) (Either SomeException b))-waitEitherCatch = Unsafe.waitEitherCatch+waitEitherCatch = (liftBase .) . A.waitEitherCatch \\ (inst :: Forall (Pure m) :- Pure m a) \\ (inst :: Forall (Pure m) :- Pure m b) -- | Generalized version of 'A.waitEitherCancel'. waitEitherCancel- :: forall m a b. (MonadBaseControl IO m, Forall (Pure m))+ :: forall m a b. (MonadBase IO m, Forall (Pure m)) => Async a -> Async b -> m (Either a b)-waitEitherCancel = Unsafe.waitEitherCancel+waitEitherCancel = (liftBase .) . A.waitEitherCancel \\ (inst :: Forall (Pure m) :- Pure m a) \\ (inst :: Forall (Pure m) :- Pure m b) -- | Generalized version of 'A.waitEitherCatchCancel'. waitEitherCatchCancel- :: forall m a b. (MonadBaseControl IO m, Forall (Pure m))+ :: forall m a b. (MonadBase IO m, Forall (Pure m)) => Async a -> Async b -> m (Either (Either SomeException a) (Either SomeException b))-waitEitherCatchCancel = Unsafe.waitEitherCatchCancel+waitEitherCatchCancel = (liftBase .) . A.waitEitherCatchCancel \\ (inst :: Forall (Pure m) :- Pure m a) \\ (inst :: Forall (Pure m) :- Pure m b) +-- | Generalized version of 'A.waitEither_'+waitEither_ :: MonadBase IO m => Async a -> Async b -> m ()+waitEither_ = Unsafe.waitEither_+ -- | Generalized version of 'A.waitBoth'. waitBoth- :: forall m a b. (MonadBaseControl IO m, Forall (Pure m))+ :: forall m a b. (MonadBase IO m, Forall (Pure m)) => Async a -> Async b -> m (a, b)-waitBoth = Unsafe.waitBoth+waitBoth = (liftBase .) . A.waitBoth \\ (inst :: Forall (Pure m) :- Pure m a) \\ (inst :: Forall (Pure m) :- Pure m b) @@ -306,25 +310,29 @@ race :: forall m a b. (MonadBaseControl IO m, Forall (Pure m)) => m a -> m b -> m (Either a b)-race = Unsafe.race- \\ (inst :: Forall (Pure m) :- Pure m a)- \\ (inst :: Forall (Pure m) :- Pure m b)+race = liftBaseOp2_ A.race -- | Generalized version of 'A.race_'. race_ :: forall m a b. (MonadBaseControl IO m, Forall (Pure m)) => m a -> m b -> m ()-race_ = Unsafe.race_- \\ (inst :: Forall (Pure m) :- Pure m a)- \\ (inst :: Forall (Pure m) :- Pure m b)+race_ = liftBaseOp2_ A.race_ -- | Generalized version of 'A.concurrently'. concurrently :: forall m a b. (MonadBaseControl IO m, Forall (Pure m)) => m a -> m b -> m (a, b)-concurrently = Unsafe.concurrently- \\ (inst :: Forall (Pure m) :- Pure m a)- \\ (inst :: Forall (Pure m) :- Pure m b)+concurrently = liftBaseOp2_ A.concurrently++-- | Similar to 'A.liftBaseOp_' but takes a binary function+-- and leverages @'StM' m a ~ a@.+liftBaseOp2_+ :: forall base m a b c. (MonadBaseControl base m, Forall (Pure m))+ => (base a -> base b -> base c)+ -> m a -> m b -> m c+liftBaseOp2_ f left right = liftBaseWith $ \run -> f+ (run left \\ (inst :: Forall (Pure m) :- Pure m a))+ (run right \\ (inst :: Forall (Pure m) :- Pure m b)) -- | Generalized version of 'A.mapConcurrently'. mapConcurrently