acid-state 0.7.9 → 0.7.10
raw patch · 3 files changed
+46/−32 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- acid-state.cabal +1/−1
- examples/RemoteServer.hs +7/−1
- src/Data/Acid/Local.hs +38/−30
acid-state.cabal view
@@ -7,7 +7,7 @@ -- The package version. See the Haskell package versioning policy -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for -- standards guiding when and how versions should be incremented.-Version: 0.7.9+Version: 0.7.10 -- A short (one-line) description of the package. Synopsis: Add ACID guarantees to any serializable Haskell data structure.
examples/RemoteServer.hs view
@@ -2,6 +2,7 @@ module Main (main) where import Data.Acid+import Data.Acid.Local import Data.Acid.Remote (acidServer) import Control.Exception (bracket)@@ -16,6 +17,11 @@ main :: IO () main = bracket- (openLocalState $ StressState 0)+ (do putStrLn "Loading checkpoint"+ mkAcid <- prepareLocalState $ StressState 0+ putStrLn "Waiting for lock/replaying events"+ acid <- mkAcid+ putStrLn "Done."+ return acid) closeAcidState (\s -> acidServer s (PortNumber 8080))
src/Data/Acid/Local.hs view
@@ -249,42 +249,50 @@ -- found. -> Bool -- ^ True if we should wait for the lock to be released. -> IO (IO (AcidState st))-resumeLocalStateFrom directory initialState doWaitForLock = do- firstLock <- if not doWaitForLock then obtainPrefixLock lockFile else return undefined-- core <- mkCore (eventsToMethods acidEvents) initialState- mbLastCheckpoint <- Log.newestEntry checkpointsLogKey- n <- case mbLastCheckpoint of- Nothing- -> return 0- Just (Checkpoint eventCutOff content)- -> do modifyCoreState_ core (\_oldState -> case runGetLazy safeGet content of- Left msg -> checkpointRestoreError msg- Right val -> return val)- return eventCutOff- return $ do- secondLock <- if doWaitForLock then waitForLock lockFile else return undefined-- eventsLog <- openFileLog eventsLogKey- events <- readEntriesFrom eventsLog n- mapM_ (runColdMethod core) events- ensureLeastEntryId eventsLog n- checkpointsLog <- openFileLog checkpointsLogKey- stateCopy <- newIORef undefined- withCoreState core (writeIORef stateCopy)-- return $ toAcidState LocalState { localCore = core- , localCopy = stateCopy- , localEvents = eventsLog- , localCheckpoints = checkpointsLog- , localLock = if doWaitForLock then secondLock else firstLock- }+resumeLocalStateFrom directory initialState doWaitForLock =+ case doWaitForLock of+ True -> do+ (n, st) <- loadCheckpoint+ return $ do+ lock <- waitForLock lockFile+ replayEvents lock n st+ False -> do+ lock <- obtainPrefixLock lockFile+ (n, st) <- loadCheckpoint+ return $ do+ replayEvents lock n st where lockFile = directory </> "open" eventsLogKey = LogKey { logDirectory = directory , logPrefix = "events" } checkpointsLogKey = LogKey { logDirectory = directory , logPrefix = "checkpoints" }+ loadCheckpoint = do+ mbLastCheckpoint <- Log.newestEntry checkpointsLogKey+ case mbLastCheckpoint of+ Nothing ->+ return (0, initialState)+ Just (Checkpoint eventCutOff content) -> do+ case runGetLazy safeGet content of+ Left msg -> checkpointRestoreError msg+ Right val -> return (eventCutOff, val)+ replayEvents lock n st = do+ core <- mkCore (eventsToMethods acidEvents) st++ eventsLog <- openFileLog eventsLogKey+ events <- readEntriesFrom eventsLog n+ mapM_ (runColdMethod core) events+ ensureLeastEntryId eventsLog n+ checkpointsLog <- openFileLog checkpointsLogKey+ stateCopy <- newIORef undefined+ withCoreState core (writeIORef stateCopy)++ return $ toAcidState LocalState { localCore = core+ , localCopy = stateCopy+ , localEvents = eventsLog+ , localCheckpoints = checkpointsLog+ , localLock = lock+ } waitForLock :: FilePath -> IO PrefixLock waitForLock path = go undefined