packages feed

Concurrent-Cache (empty) → 0.1.0.0

raw patch · 5 files changed

+124/−0 lines, 5 filesdep +basesetup-changed

Dependencies added: base

Files

+ ChangeLog.md view
@@ -0,0 +1,5 @@+# Revision history for Concurrent-Cache++## 0.1.0.0  -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ Concurrent-Cache.cabal view
@@ -0,0 +1,29 @@+-- Initial Concurrent-Cache.cabal generated by cabal init.  For further +-- documentation, see http://haskell.org/cabal/users-guide/++name:                Concurrent-Cache+version:             0.1.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.+license:             BSD3+license-file:        LICENSE+author:              Marcus Ofenhed+maintainer:          marcus@conditionraise.se+-- copyright:           +category:            Concurrency+build-type:          Simple+extra-source-files:  ChangeLog.md+cabal-version:       >=1.10++library+  exposed-modules:     Control.Concurrent.Cache+  -- other-modules:       +  -- other-extensions:    +  build-depends:       base >=4.9 && <4.10+  -- hs-source-dirs:      +  default-language:    Haskell2010++Source-Repository head+  Type:       git+  Location:   git://github.com/Ofenhed/Concurrent-Cache.git
+ Control/Concurrent/Cache.hs view
@@ -0,0 +1,58 @@+module Control.Concurrent.Cache (CachedData, fetch, createCache) 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))++-- |Fetch data from a cache+fetch :: CachedData a+      -- ^ @Cache@, the cache to fetch a value from+      -> IO (a)+fetch (ReadOnceCachedData mvar) = go where+  go = readMVar mvar >>= \cached -> do+    case cached of+      Left _ -> do+        modifyMVar_ mvar $ \cached' -> case cached' of+                                          Left x -> do liftM Right x+                                          Right x -> return $ Right x+        go+      Right value -> return value++fetch (TimedCachedData (timeout, mvar)) = go where+  go = readMVar mvar >>= \(thread,_,value) -> do+    case value of+      Nothing -> do+        modifyMVar_ mvar $ \mvar'@(threadId', action', value') -> case value' of+                                          Nothing -> do newVal <- action'+                                                        return (threadId', action', Just newVal)+                                          Just x -> return $ mvar'+        go+      Just value' -> do +        when (not $ isNothing thread) $ let Just thread' = thread in killThread thread'+        modifyMVar_ mvar $ \(_, action', value') -> do+          newThreadId <- forkIO $ do+            threadDelay timeout+            putStrLn "Deleting"+            modifyMVar_ mvar $ \(_, action'', _) -> return (Nothing, action'', Nothing)+          return (Just newThreadId, action', value')+        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)+            -- ^ @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+  var <- newMVar $ Left action+  return $ ReadOnceCachedData var++createCache timeout action = do+  var <- newMVar (Nothing, action, Nothing)+  return $ TimedCachedData (timeout, var)
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2016, Marcus Ofenhed++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Marcus Ofenhed nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain