acid-state 0.12.4 → 0.13.0
raw patch · 4 files changed
+62/−15 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.Acid.Abstract: AcidState :: (forall event. (UpdateEvent event, EventState event ~ st) => event -> IO (MVar (EventResult event))) -> (Tagged ByteString -> IO (MVar ByteString)) -> (forall event. (QueryEvent event, EventState event ~ st) => event -> IO (EventResult event)) -> (Tagged ByteString -> IO ByteString) -> IO () -> IO () -> IO () -> AnyState st -> AcidState st
+ Data.Acid.Abstract: _query :: AcidState st -> forall event. (QueryEvent event, EventState event ~ st) => event -> IO (EventResult event)
+ Data.Acid.Abstract: _scheduleUpdate :: AcidState st -> forall event. (UpdateEvent event, EventState event ~ st) => event -> IO (MVar (EventResult event))
+ Data.Acid.Abstract: acidSubState :: AcidState st -> AnyState st
+ Data.Acid.Abstract: closeAcidState :: AcidState st -> IO ()
+ Data.Acid.Abstract: createArchive :: AcidState st -> IO ()
+ Data.Acid.Abstract: createCheckpoint :: AcidState st -> IO ()
+ Data.Acid.Abstract: data AcidState st
+ Data.Acid.Abstract: downcast :: (Typeable sub, Typeable st) => AcidState st -> sub st
+ Data.Acid.Abstract: groupUpdates :: UpdateEvent event => AcidState (EventState event) -> [event] -> IO ()
+ Data.Acid.Abstract: mkAnyState :: Typeable sub_st => sub_st st -> AnyState st
+ Data.Acid.Abstract: query :: QueryEvent event => AcidState (EventState event) -> event -> IO (EventResult event)
+ Data.Acid.Abstract: query' :: (QueryEvent event, MonadIO m) => AcidState (EventState event) -> event -> m (EventResult event)
+ Data.Acid.Abstract: queryCold :: AcidState st -> Tagged ByteString -> IO ByteString
+ Data.Acid.Abstract: scheduleColdUpdate :: AcidState st -> Tagged ByteString -> IO (MVar ByteString)
+ Data.Acid.Abstract: scheduleUpdate :: UpdateEvent event => AcidState (EventState event) -> event -> IO (MVar (EventResult event))
+ Data.Acid.Abstract: update :: UpdateEvent event => AcidState (EventState event) -> event -> IO (EventResult event)
+ Data.Acid.Abstract: update' :: (UpdateEvent event, MonadIO m) => AcidState (EventState event) -> event -> m (EventResult event)
+ Data.Acid.CRC: crc16 :: ByteString -> Word16
+ Data.Acid.Core: Method :: (method -> State (MethodState method) (MethodResult method)) -> MethodContainer (MethodState method)
+ Data.Acid.Core: class (Typeable ev, SafeCopy ev, Typeable (MethodResult ev), SafeCopy (MethodResult ev)) => Method ev where type family MethodResult ev type family MethodState ev methodTag ev = pack (showQualifiedTypeRep (typeOf ev))
+ Data.Acid.Core: closeCore :: Core st -> IO ()
+ Data.Acid.Core: closeCore' :: Core st -> (st -> IO ()) -> IO ()
+ Data.Acid.Core: data Core st
+ Data.Acid.Core: data MethodContainer st
+ Data.Acid.Core: lookupColdMethod :: Core st -> Tagged ByteString -> State st ByteString
+ Data.Acid.Core: lookupHotMethod :: Method method => MethodMap (MethodState method) -> method -> State (MethodState method) (MethodResult method)
+ Data.Acid.Core: methodTag :: Method ev => ev -> Tag
+ Data.Acid.Core: mkCore :: [MethodContainer st] -> st -> IO (Core st)
+ Data.Acid.Core: mkMethodMap :: [MethodContainer st] -> MethodMap st
+ Data.Acid.Core: modifyCoreState :: Core st -> (st -> IO (st, a)) -> IO a
+ Data.Acid.Core: modifyCoreState_ :: Core st -> (st -> IO st) -> IO ()
+ Data.Acid.Core: runColdMethod :: Core st -> Tagged ByteString -> IO ByteString
+ Data.Acid.Core: runHotMethod :: Method method => Core (MethodState method) -> method -> IO (MethodResult method)
+ Data.Acid.Core: type MethodMap st = Map Tag (MethodContainer st)
+ Data.Acid.Core: type Tagged a = (Tag, a)
+ Data.Acid.Core: withCoreState :: Core st -> (st -> IO a) -> IO a
+ Data.Acid.Local: Checkpoint :: EntryId -> ByteString -> Checkpoint
+ Data.Acid.Local: LocalState :: Core st -> IORef st -> FileLog (Tagged ByteString) -> FileLog Checkpoint -> PrefixLock -> LocalState st
+ Data.Acid.Local: data Checkpoint
+ Data.Acid.Local: data LocalState st
+ Data.Acid.Local: localCheckpoints :: LocalState st -> FileLog Checkpoint
+ Data.Acid.Local: localCopy :: LocalState st -> IORef st
+ Data.Acid.Local: localCore :: LocalState st -> Core st
+ Data.Acid.Local: localEvents :: LocalState st -> FileLog (Tagged ByteString)
+ Data.Acid.Local: localLock :: LocalState st -> PrefixLock
+ Data.Acid.Local: scheduleLocalColdUpdate' :: LocalState st -> Tagged ByteString -> MVar ByteString -> IO (IO ())
+ Data.Acid.Local: scheduleLocalUpdate' :: UpdateEvent event => LocalState (EventState event) -> event -> MVar (EventResult event) -> IO (IO ())
+ Data.Acid.Log: FileLog :: LogKey object -> MVar FHandle -> TVar EntryId -> TVar ([ByteString], [IO ()]) -> [ThreadId] -> FileLog object
+ Data.Acid.Log: LogKey :: FilePath -> String -> LogKey object
+ Data.Acid.Log: archiveFileLog :: FileLog object -> EntryId -> IO ()
+ Data.Acid.Log: askCurrentEntryId :: FileLog object -> IO EntryId
+ Data.Acid.Log: closeFileLog :: FileLog object -> IO ()
+ Data.Acid.Log: cutFileLog :: FileLog object -> IO EntryId
+ Data.Acid.Log: data FileLog object
+ Data.Acid.Log: data LogKey object
+ Data.Acid.Log: ensureLeastEntryId :: FileLog object -> EntryId -> IO ()
+ Data.Acid.Log: logCurrent :: FileLog object -> MVar FHandle
+ Data.Acid.Log: logDirectory :: LogKey object -> FilePath
+ Data.Acid.Log: logIdentifier :: FileLog object -> LogKey object
+ Data.Acid.Log: logNextEntryId :: FileLog object -> TVar EntryId
+ Data.Acid.Log: logPrefix :: LogKey object -> String
+ Data.Acid.Log: logQueue :: FileLog object -> TVar ([ByteString], [IO ()])
+ Data.Acid.Log: logThreads :: FileLog object -> [ThreadId]
+ Data.Acid.Log: newestEntry :: SafeCopy object => LogKey object -> IO (Maybe object)
+ Data.Acid.Log: openFileLog :: LogKey object -> IO (FileLog object)
+ Data.Acid.Log: pushAction :: FileLog object -> IO () -> IO ()
+ Data.Acid.Log: pushEntry :: SafeCopy object => FileLog object -> object -> IO () -> IO ()
+ Data.Acid.Log: readEntriesFrom :: SafeCopy object => FileLog object -> EntryId -> IO [object]
+ Data.Acid.Log: rollbackTo :: SafeCopy object => LogKey object -> EntryId -> IO ()
+ Data.Acid.Log: rollbackWhile :: SafeCopy object => LogKey object -> (object -> Bool) -> IO ()
+ Data.Acid.Log: type EntryId = Int
Files
- acid-state.cabal +7/−6
- src/Data/Acid/Abstract.hs +7/−8
- src/Data/Acid/Local.hs +47/−0
- src/Data/Acid/Log.hs +1/−1
acid-state.cabal view
@@ -1,5 +1,5 @@ Name: acid-state-Version: 0.12.4+Version: 0.13.0 Synopsis: Add ACID guarantees to any serializable Haskell data structure. Description: Use regular Haskell data structures as your database and get stronger ACID guarantees than most RDBMS offer. Homepage: http://acid-state.seize.it/@@ -24,12 +24,13 @@ Exposed-Modules: Data.Acid, Data.Acid.Local, Data.Acid.Memory, Data.Acid.Memory.Pure, Data.Acid.Remote,- Data.Acid.Advanced-- Other-modules: Data.Acid.Log, Data.Acid.Archive,- Data.Acid.CRC, Paths_acid_state,- Data.Acid.TemplateHaskell, Data.Acid.Common, FileIO,+ Data.Acid.Advanced,+ Data.Acid.Log, Data.Acid.CRC, Data.Acid.Abstract, Data.Acid.Core++ Other-modules: Data.Acid.Archive,+ Paths_acid_state,+ Data.Acid.TemplateHaskell, Data.Acid.Common, FileIO Build-depends: array, base >= 4 && < 5,
src/Data/Acid/Abstract.hs view
@@ -35,15 +35,14 @@ {-| State container offering full ACID (Atomicity, Consistency, Isolation and Durability) guarantees. - [@Atomicity@] State changes are all-or-nothing. This is what you'd expect of any state- variable in Haskell and AcidState doesn't change that.-+ [@Atomicity@] State changes are all-or-nothing. This is what you'd expect+ of any state variable in Haskell and AcidState doesn't+ change that. [@Consistency@] No event or set of events will break your data invariants.-- [@Isolation@] Transactions cannot interfere with each other even when issued in parallel.-- [@Durability@] Successful transaction are guaranteed to survive unexpected system shutdowns- (both those caused by hardware and software).+ [@Isolation@] Transactions cannot interfere with each other even when+ issued in parallel.+ [@Durability@] Successful transaction are guaranteed to survive unexpected+ system shutdowns (both those caused by hardware and software). -} data AcidState st = AcidState {
src/Data/Acid/Local.hs view
@@ -17,7 +17,11 @@ , openLocalStateFrom , prepareLocalState , prepareLocalStateFrom+ , scheduleLocalUpdate'+ , scheduleLocalColdUpdate' , createCheckpointAndClose+ , LocalState(..)+ , Checkpoint(..) ) where import Data.Acid.Log as Log@@ -95,6 +99,32 @@ return mvar where hotMethod = lookupHotMethod (coreMethods (localCore acidState)) event +-- | Same as scheduleLocalUpdate but does not immediately change the localCopy+-- and return the result mvar - returns an IO action to do this instead. Take+-- care to run actions of multiple Updates in the correct order as otherwise+-- Queries will operate on outdated state.+scheduleLocalUpdate' :: UpdateEvent event => LocalState (EventState event) -> event -> MVar (EventResult event) -> IO (IO ())+scheduleLocalUpdate' acidState event mvar+ = do+ let encoded = runPutLazy (safePut event)++ -- It is important that we encode the event now so that we can catch+ -- any exceptions (see nestedStateError in examples/errors/Exceptions.hs)+ evaluate (Lazy.length encoded)++ act <- modifyCoreState (localCore acidState) $ \st ->+ do let !(result, !st') = runState hotMethod st+ -- Schedule the log entry. Very important that it happens when 'localCore' is locked+ -- to ensure that events are logged in the same order that they are executed.+ pushEntry (localEvents acidState) (methodTag event, encoded) $ return ()+ let action = do writeIORef (localCopy acidState) st'+ putMVar mvar result+ return (st', action)+ -- this is the action to update state for queries and release the+ -- result into the supplied mvar+ return act+ where hotMethod = lookupHotMethod (coreMethods (localCore acidState)) event+ scheduleLocalColdUpdate :: LocalState st -> Tagged ByteString -> IO (MVar ByteString) scheduleLocalColdUpdate acidState event = do mvar <- newEmptyMVar@@ -106,6 +136,23 @@ putMVar mvar result return st' return mvar+ where coldMethod = lookupColdMethod (localCore acidState) event++-- | Same as scheduleLocalColdUpdate but does not immediately change the+-- localCopy and return the result mvar - returns an IO action to do this+-- instead. Take care to run actions of multiple Updates in the correct order as+-- otherwise Queries will operate on outdated state.+scheduleLocalColdUpdate' :: LocalState st -> Tagged ByteString -> MVar ByteString -> IO (IO ())+scheduleLocalColdUpdate' acidState event mvar+ = do act <- modifyCoreState (localCore acidState) $ \st ->+ do let !(result, !st') = runState coldMethod st+ -- Schedule the log entry. Very important that it happens when 'localCore' is locked+ -- to ensure that events are logged in the same order that they are executed.+ pushEntry (localEvents acidState) event $ return ()+ let action = do writeIORef (localCopy acidState) st'+ putMVar mvar result+ return (st', action)+ return act where coldMethod = lookupColdMethod (localCore acidState) event -- | Issue a Query event and wait for its result. Events may be issued in parallel.
src/Data/Acid/Log.hs view
@@ -3,7 +3,7 @@ -- extendible array of entries. -- module Data.Acid.Log- ( FileLog+ ( FileLog(..) , LogKey(..) , EntryId , openFileLog