Concurrent-Cache 0.1.0.2 → 0.2.0.0
raw patch · 3 files changed
+38/−22 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Control.Concurrent.Cache: createCache :: Int -> IO (a) -> IO (CachedData a)
+ Control.Concurrent.Cache: createReadOnceCache :: IO (a) -> IO (CachedData a)
+ Control.Concurrent.Cache: createTimedCache :: Int -> Bool -> IO (a) -> IO (CachedData a)
Files
- ChangeLog.md +0/−5
- Concurrent-Cache.cabal +1/−2
- Control/Concurrent/Cache.hs +37/−15
− ChangeLog.md
@@ -1,5 +0,0 @@-# Revision history for Concurrent-Cache--## 0.1.0.0 -- YYYY-mm-dd--* First version. Released on an unsuspecting world.
Concurrent-Cache.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: Concurrent-Cache-version: 0.1.0.2+version: 0.2.0.0 synopsis: A Cached variable for IO functions. description: This package allows for caching IO functions, either on a timeout or designed to only fetch once.@@ -13,7 +13,6 @@ -- copyright: category: Concurrency build-type: Simple-extra-source-files: ChangeLog.md cabal-version: >=1.10 library
Control/Concurrent/Cache.hs view
@@ -1,11 +1,13 @@-module Control.Concurrent.Cache (CachedData, fetch, createCache) where+module Control.Concurrent.Cache (CachedData, fetch, createReadOnceCache, createTimedCache) where import Data.Maybe (isNothing) import Control.Concurrent (forkIO, threadDelay, killThread, MVar, modifyMVar_, readMVar, ThreadId, newMVar) import Control.Monad (when, liftM) -data CachedData a = TimedCachedData (Int, (MVar (Maybe ThreadId, IO a, Maybe a))) | ReadOnceCachedData (MVar (Either (IO a) a))+data Timeout = TimeSinceCreation Int | TimeSinceLastRead Int +data CachedData a = TimedCachedData (Timeout, (MVar (Maybe ThreadId, IO a, Maybe a))) | ReadOnceCachedData (MVar (Either (IO a) a))+ -- |Fetch data from a cache fetch :: CachedData a -- ^ @Cache@, the cache to fetch a value from@@ -32,28 +34,48 @@ Just x -> return $ mvar' go Just value' -> do - modifyMVar_ mvar $ \(thread', action', value') -> do- when (not $ isNothing thread') $ let Just thread'' = thread' in killThread thread''- newThreadId <- forkIO $ do- threadDelay timeout- modifyMVar_ mvar $ \(_, action'', _) -> return (Nothing, action'', Nothing)- return (Just newThreadId, action', value')+ modifyMVar_ mvar $ \mvar'@(thread', action', value') -> do+ let newThread x = do threadDelay x+ modifyMVar_ mvar $ \(_, action'', _) -> return (Nothing, action'', Nothing)+ case timeout of+ TimeSinceLastRead time -> do+ when (not $ isNothing thread') $ let Just thread'' = thread' in killThread thread''+ newThreadId <- forkIO $ newThread time+ return (Just newThreadId, action', value')+ TimeSinceCreation time -> do+ if (isNothing thread')+ then do newThread' <- forkIO $ newThread time+ return (Just newThread', action', value')+ else return mvar' return value' -- |Create a cache with a timeout from an (IO ()) function.-createCache :: Int- -- ^ @Timeout@ in microseconds before the cache is erased, 0 to- -- disable emptying of the cache- -> IO (a)+createReadOnceCache :: IO (a) -- ^ @Fetcher@, the function that returns the data which should -- be cached. If @Timeout@ is not set to zero, this function -- must be allowed to be called more than once. -> IO (CachedData a)-createCache 0 action = do+createReadOnceCache action = do var <- newMVar $ Left action return $ ReadOnceCachedData var -createCache timeout action = do+-- |Create a cache with a timeout from an (IO ()) function.+createTimedCache :: Int+ -- ^ @Timeout@ in microseconds before the cache is erased, 0 to+ -- disable emptying of the cache+ -> Bool+ -- ^ @resetTimerOnRead@, if true the timeout will be reset+ -- every time the cache is read, otherwise it will only be+ -- reset when the cached value is set.+ -> IO (a)+ -- ^ @Fetcher@, the function that returns the data which should+ -- be cached. If @Timeout@ is not set to zero, this function+ -- must be allowed to be called more than once.+ -> IO (CachedData a)+createTimedCache timeout resetOnRead action = do var <- newMVar (Nothing, action, Nothing)- return $ TimedCachedData (timeout, var)+ let timeout' = if resetOnRead+ then TimeSinceLastRead timeout+ else TimeSinceCreation timeout+ return $ TimedCachedData (timeout', var)