io-throttle (empty) → 0.1.0
raw patch · 5 files changed
+110/−0 lines, 5 filesdep +SafeSemaphoredep +basedep +io-throttlesetup-changed
Dependencies added: SafeSemaphore, base, io-throttle, threads
Files
- LICENSE +20/−0
- Setup.hs +2/−0
- io-throttle.cabal +38/−0
- src/Control/Concurrent/Throttle.hs +33/−0
- test/Main.hs +17/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2014 Rodrigo Setti++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ io-throttle.cabal view
@@ -0,0 +1,38 @@+name : io-throttle+version : 0.1.0+synopsis : Limit number of IO actions started per second+homepage : http://github.com/rodrigosetti/io-throttle+license : MIT+license-file : LICENSE+copyright : (c) 2014, Rodrigo Setti+author : Rodrigo Setti+maintainer : rodrigosetti@gmail.com+category : Concurrency+build-type : Simple+cabal-version : >=1.10+description :+ Limit the number of tasks started per second. The throttle function will+ run all actions concurrently but only starting a certain number per+ second. It will wait for all tasks and return the results in a list.++source-repository head+ type : git+ location : git@github.com:rodrigosetti/io-throttle.git++library+ exposed-modules : Control.Concurrent.Throttle+ build-depends : base == 4.*+ , threads == 0.5.*+ , SafeSemaphore == 0.10.*+ hs-source-dirs : src+ default-language : Haskell2010+ ghc-options : -Wall++test-suite test-io-threads+ default-language : Haskell2010+ hs-source-dirs : test+ main-is : Main.hs+ type : exitcode-stdio-1.0+ build-depends : base == 4.*+ , io-throttle+
+ src/Control/Concurrent/Throttle.hs view
@@ -0,0 +1,33 @@+{-|+Module : Control.Concurrent.Throttle+Description : Limit the number of IO actions per second+Copyright : (c) 2014, Rodrigo Setti+License : MIT+Maintainer : rodrigosetti@gmail.com+Stability : experimental+Portability : POSIX+-}+module Control.Concurrent.Throttle (throttle) where++import Control.Concurrent+import Control.Concurrent.MSemN+import qualified Control.Concurrent.Thread as Thread+import Control.Exception+import Control.Monad++-- | Limit the number of @tasks@ started per second. @throttle@ will run all+-- actions concurrently but only starting a certain number per second. It+-- will wait for all tasks and return the results in a list.+throttle :: Int -- ^ number of tasks per second (TPS)+ -> [IO a] -- ^ the tasks to run concurrently but limited by TPS+ -> IO [a] -- ^ the tasks results+throttle tps tasks =+ do sem <- new tps+ let runTask task = liftM snd $ wait sem 1 >> Thread.forkIO task+ timeResetWorker = forever $ threadDelay 1000000 >> signalF sem (\i -> (tps-i, ()))+ runAllTasks = mapM runTask tasks+ mapM Thread.result =<< sequence =<< bracket (forkIO timeResetWorker)+ killThread+ (const runAllTasks)++
+ test/Main.hs view
@@ -0,0 +1,17 @@+module Main where++import Control.Concurrent+import Control.Concurrent.Throttle+import Control.Monad++main :: IO ()+main = do res <- throttle 5 tasks+ putStrLn "-------------"+ forM_ res print+ where+ tasks = map performTask ([1..100] :: [Int])+ performTask i = do putStrLn $ "task start " ++ show i+ threadDelay $ i * 10000+ putStrLn $ "task done " ++ show i+ return i+