packages feed

pooled-io 0.0.1.2 → 0.0.2

raw patch · 2 files changed

+89/−3 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Control.Concurrent.PooledIO.Sequence: async :: In -> IO () -> IO ()
+ Control.Concurrent.PooledIO.Sequence: data In
+ Control.Concurrent.PooledIO.Sequence: data Out
+ Control.Concurrent.PooledIO.Sequence: new :: IO (In, Out)
+ Control.Concurrent.PooledIO.Sequence: run :: Out -> IO ()
+ Control.Concurrent.PooledIO.Sequence: sync :: In -> IO a -> IO a

Files

pooled-io.cabal view
@@ -1,5 +1,5 @@ Name:             pooled-io-Version:          0.0.1.2+Version:          0.0.2 License:          BSD3 License-File:     LICENSE Author:           Henning Thielemann <haskell@henning-thielemann.de>@@ -26,6 +26,12 @@   * "Control.Concurrent.PooledIO.InOrder":     run jobs in parallel with data dependencies like @make -j n@   .+  Additionally there is the module+  "Control.Concurrent.PooledIO.Sequence"+  that helps to serialize I/O actions from multiple threads.+  It is certainly most useful in connection with+  "Control.Concurrent.PooledIO.Independent".+  .   Related packages:   .   * @lazyio@: interleave IO actions in a single thread@@ -34,7 +40,7 @@     but do not throttle concurrency with respect to number of available cores   .   * @parallel-tasks@:-Tested-With:      GHC==7.4.1+Tested-With:      GHC==7.4.2, GHC==7.8.4, GHC==7.10.1 Cabal-Version:    >=1.8 Build-Type:       Simple @@ -43,7 +49,7 @@   default:     False  Source-Repository this-  Tag:         0.0.1.2+  Tag:         0.0.2   Type:        darcs   Location:    http://code.haskell.org/~thielema/pooled-io/ @@ -67,6 +73,7 @@     Control.Concurrent.PooledIO.Independent     Control.Concurrent.PooledIO.Final     Control.Concurrent.PooledIO.InOrder+    Control.Concurrent.PooledIO.Sequence   Other-Modules:     Control.Concurrent.PooledIO.Monad 
+ src/Control/Concurrent/PooledIO/Sequence.hs view
@@ -0,0 +1,79 @@+{- |+Functions for sequencing actions requested from concurrent threads.++Here is an example usage:++> import qualified Control.Concurrent.PooledIO.Independent as Parallel+> import qualified Control.Concurrent.PooledIO.Sequence as Sequence+>+> thread :: Sequence.In -> FilePath -> IO ()+> thread seqIn name = do+>    txt <- Sequence.sync seqIn $ readFile (name ++ ".in")+>    -- evaluate result with ($!!) before sending it to the sequencing thread+>    Sequence.async seqIn . writeFile (name ++ ".out") $!! processMyText txt+>    doFurtherStuff+>    -- block main program until completion+>    Sequence.sync seqIn $ return ()+>+> main :: IO ()+> main = do+>    (seqIn, seqOut) <- Sequence.new+>    void $ forkIO $ Sequence.run seqOut+>    Parallel.run $ map (thread seqIn) ["a", "b", "c"]+-}+module Control.Concurrent.PooledIO.Sequence (In, Out, new, run, async, sync) where++import qualified Control.Concurrent.Split.Chan as Chan+import qualified Control.Concurrent.Split.MVar as MVar++import Control.Monad (join, forever)++import Data.Tuple.HT (mapPair)+++type Action = IO ()++newtype In = In (Chan.In Action)+newtype Out = Out (Chan.Out Action)+++new :: IO (In, Out)+new = fmap (mapPair (In,Out)) Chan.new++{- |+Run the sequencing thread.+You will usually fork it.+-}+run :: Out -> IO ()+run (Out chan) =+   forever $ join $ Chan.read chan++{- |+This is primarily intended for output functions.+You should make sure that the emitted data is evaluated before calling 'async'.+Otherwise the sequencing thread will evaluate it+and thus not much parallelization will happen.++Example:++> async seqIn . writeFile "foobar.txt" $!! show result+-}+async :: In -> IO () -> IO ()+async (In chan) act =+   Chan.write chan act++{- |+This is primarily intended for input functions.+You should also call it at the end of a thread in order to make sure+that all your asynchronous actions are completed.+It will actually also wait for the actions that were requested by other threads.+However, I think this should not hurt+since after completion of the current thread+another one will be started and it will certainly begin with an input action,+which has to be queued anyway.+-}+sync :: In -> IO a -> IO a+sync chan act = do+   (resultIn, resultOut) <- MVar.newEmpty+   async chan $ act >>= MVar.put resultIn+   MVar.take resultOut