Portability | non-portable (uses GHC extensions) |
---|---|
Maintainer | lemmih@gmail.com |
AcidState container using a transaction log on disk. The term 'Event' is loosely used for transactions with ACID guarantees. 'Method' is loosely used for state operations without ACID guarantees (see Data.Acid.Core).
- class SafeCopy st => IsAcidic st where
- acidEvents :: [Event st]
- data AcidState st
- data Event st where
- UpdateEvent :: UpdateEvent ev => (ev -> Update (EventState ev) (EventResult ev)) -> Event (EventState ev)
- QueryEvent :: QueryEvent ev => (ev -> Query (EventState ev) (EventResult ev)) -> Event (EventState ev)
- type EventResult ev = MethodResult ev
- type EventState ev = MethodState ev
- class Method ev => UpdateEvent ev
- class Method ev => QueryEvent ev
- data Update st a
- data Query st a
- openAcidState :: (Typeable st, IsAcidic st) => st -> IO (AcidState st)
- openAcidStateFrom :: IsAcidic st => FilePath -> st -> IO (AcidState st)
- closeAcidState :: AcidState st -> IO ()
- createCheckpoint :: SafeCopy st => AcidState st -> IO ()
- createCheckpointAndClose :: SafeCopy st => AcidState st -> IO ()
- update :: UpdateEvent event => AcidState (EventState event) -> event -> IO (EventResult event)
- scheduleUpdate :: UpdateEvent event => AcidState (EventState event) -> event -> IO (MVar (EventResult event))
- query :: QueryEvent event => AcidState (EventState event) -> event -> IO (EventResult event)
- update' :: (UpdateEvent event, MonadIO m) => AcidState (EventState event) -> event -> m (EventResult event)
- query' :: (QueryEvent event, MonadIO m) => AcidState (EventState event) -> event -> m (EventResult event)
- runQuery :: Query st a -> Update st a
Documentation
class SafeCopy st => IsAcidic st whereSource
:: [Event st] | List of events capable of updating or querying the state. |
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.
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 system failure (both hardware and software).
We distinguish between events that modify the state and those that do not.
UpdateEvents are executed in a MonadState context and have to be serialized to disk before they are considered durable.
QueryEvents are executed in a MonadReader context and obviously do not have to be serialized to disk.
UpdateEvent :: UpdateEvent ev => (ev -> Update (EventState ev) (EventResult ev)) -> Event (EventState ev) | |
QueryEvent :: QueryEvent ev => (ev -> Query (EventState ev) (EventResult ev)) -> Event (EventState ev) |
type EventResult ev = MethodResult evSource
Events return the same thing as Methods. The exact type of EventResult
depends on the event.
type EventState ev = MethodState evSource
class Method ev => UpdateEvent ev Source
All UpdateEvents are also Methods.
class Method ev => QueryEvent ev Source
All QueryEvents are also Methods.
Context monad for Update events.
MonadState st (Update st) | |
Monad (Update st) | |
Functor (Update st) | |
Applicative (Update st) |
Context monad for Query events.
MonadReader st (Query st) | |
Monad (Query st) | |
Functor (Query st) | |
Applicative (Query st) |
:: (Typeable st, IsAcidic st) | |
=> st | Initial state value. This value is only used if no checkpoint is found. |
-> IO (AcidState st) |
Create an AcidState given an initial value.
This will create or resume a log found in the "state/[typeOf state]/" directory.
:: IsAcidic st | |
=> FilePath | Location of the checkpoint and transaction files. |
-> st | Initial state value. This value is only used if no checkpoint is found. |
-> IO (AcidState st) |
Create an AcidState given a log directory and an initial value.
This will create or resume a log found in directory
.
Running two AcidState's from the same directory is an error
but will not result in dataloss.
closeAcidState :: AcidState st -> IO ()Source
Close an AcidState and associated logs. Any subsequent usage of the AcidState will throw an exception.
createCheckpoint :: SafeCopy st => AcidState st -> IO ()Source
Take a snapshot of the state and save it to disk. Creating checkpoints makes it faster to resume AcidStates and you're free to create them as often or seldom as fits your needs. Transactions can run concurrently with this call.
This call will not return until the operation has succeeded.
createCheckpointAndClose :: SafeCopy st => AcidState st -> IO ()Source
Save a snapshot to disk and close the AcidState as a single atomic action. This is useful when you want to make sure that no events are saved to disk after a checkpoint.
update :: UpdateEvent event => AcidState (EventState event) -> event -> IO (EventResult event)Source
Issue an Update event and wait for its result. Once this call returns, you are guaranteed that the changes to the state are durable. Events may be issued in parallel.
It's a run-time error to issue events that aren't supported by the AcidState.
scheduleUpdate :: UpdateEvent event => AcidState (EventState event) -> event -> IO (MVar (EventResult event))Source
Issue an Update event and return immediately. The event is not durable
before the MVar has been filled but the order of events is honored.
The behavior in case of exceptions is exactly the same as for update
.
If EventA is scheduled before EventB, EventA will be executed before EventB:
do scheduleUpdate acid EventA scheduleUpdate acid EventB
query :: QueryEvent event => AcidState (EventState event) -> event -> IO (EventResult event)Source
Issue a Query event and wait for its result. Events may be issued in parallel.
update' :: (UpdateEvent event, MonadIO m) => AcidState (EventState event) -> event -> m (EventResult event)Source
Same as update
but lifted into any monad capable of doing IO.
query' :: (QueryEvent event, MonadIO m) => AcidState (EventState event) -> event -> m (EventResult event)Source
Same as query
but lifted into any monad capable of doing IO.