Concurrent-Cache 0.2.1.0 → 0.2.2.0
raw patch · 2 files changed
+14/−11 lines, 2 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- Concurrent-Cache.cabal +1/−1
- Control/Concurrent/Cache.hs +13/−10
Concurrent-Cache.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: Concurrent-Cache-version: 0.2.1.0+version: 0.2.2.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.
Control/Concurrent/Cache.hs view
@@ -1,16 +1,16 @@ module Control.Concurrent.Cache (CachedData, fetch, fetchCached, createReadOnceCache, createTimedCache) where import Data.Maybe (isNothing)-import Control.Concurrent (forkIO, threadDelay, killThread, MVar, modifyMVar_, readMVar, ThreadId, newMVar)+import Control.Concurrent (forkIO, threadDelay, killThread, MVar, modifyMVar_, readMVar, ThreadId, newMVar, mkWeakMVar)+import System.Mem.Weak (deRefWeak, Weak) import Control.Monad (when, liftM) data Timeout = TimeSinceCreation Int | TimeSinceLastRead Int +type TimedCachedDataMVar a = MVar (Maybe ThreadId, IO a, Maybe a) -data CachedData a = TimedCachedData (Timeout, (MVar (Maybe ThreadId, IO a, Maybe a))) | ReadOnceCachedData (MVar (Either (IO a) a))+data CachedData a = TimedCachedData Timeout (TimedCachedDataMVar a) (Weak (TimedCachedDataMVar a)) | ReadOnceCachedData (MVar (Either (IO a) a)) --- |Only fetch data iff it has been cached. Useful for example when--- a database connection is being cached, and it has to be closed when it--- is no longer needed, but should not be opened just to be closed.+-- |Only fetch data if it has been cached. fetchCached :: CachedData a -> IO (Maybe a) fetchCached (ReadOnceCachedData mvar) = do@@ -19,11 +19,14 @@ Left _ -> Nothing Right value -> Just value -fetchCached (TimedCachedData (timeout, mvar)) = do+fetchCached (TimedCachedData timeout mvar weakMVar) = do (_,_,value) <- readMVar mvar modifyMVar_ mvar $ \mvar'@(thread', action', value') -> do let newThread x = do threadDelay x- modifyMVar_ mvar $ \(_, action'', _) -> return (Nothing, action'', Nothing)+ dereffed <- deRefWeak weakMVar+ case dereffed of+ Just mvar'' -> modifyMVar_ mvar'' $ \(_, action'', _) -> return (Nothing, action'', Nothing)+ Nothing -> return () case timeout of TimeSinceLastRead time -> do when (not $ isNothing thread') $ let Just thread'' = thread' in killThread thread''@@ -38,7 +41,6 @@ -- |Fetch data from a cache fetch :: CachedData a- -- ^ @Cache@, the cache to fetch a value from -> IO (a) fetch state@(ReadOnceCachedData mvar) = go where go = do@@ -51,7 +53,7 @@ go Just value -> return value -fetch state@(TimedCachedData (timeout, mvar)) = go where+fetch state@(TimedCachedData timeout mvar _) = go where go = do cached <- fetchCached state case cached of@@ -92,4 +94,5 @@ let timeout' = if resetOnRead then TimeSinceLastRead timeout else TimeSinceCreation timeout- return $ TimedCachedData (timeout', var)+ weakMVar <- mkWeakMVar var $ return ()+ return $ TimedCachedData timeout' var weakMVar