{-# LANGUAGE RankNTypes, TypeFamilies, GADTs #-}moduleData.Acid.Abstract(AcidState(..),scheduleUpdate,groupUpdates,update,update',query,query',mkAnyState,downcast)whereimportData.Acid.CommonimportData.Acid.CoreimportControl.Concurrent(MVar,takeMVar)importData.ByteString.Lazy(ByteString)importControl.Monad(void)importControl.Monad.Trans(MonadIO(liftIO))importData.Typeable(Typeable1,gcast1,typeOf1)dataAnyStatestwhereAnyState::Typeable1sub_st=>sub_stst->AnyStatest-- Haddock doesn't get the types right on its own.{-| 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 unexpected system shutdowns
(both those caused by hardware and software).
-}dataAcidStatest=AcidState{_scheduleUpdate::forallevent.(UpdateEventevent,EventStateevent~st)=>event->IO(MVar(EventResultevent)),scheduleColdUpdate::TaggedByteString->IO(MVarByteString),_query::(QueryEventevent,EventStateevent~st)=>event->IO(EventResultevent),queryCold::TaggedByteString->IOByteString,-- | 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.createCheckpoint::IO(),-- | Close an AcidState and associated resources.-- Any subsequent usage of the AcidState will throw an exception.closeAcidState::IO(),acidSubState::AnyStatest}-- | 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-- @scheduleUpdate::UpdateEventevent=>AcidState(EventStateevent)->event->IO(MVar(EventResultevent))scheduleUpdate=_scheduleUpdate-- Redirection to make Haddock happy.-- | Schedule multiple Update events and wait for them to be durable, but-- throw away their results. This is useful for importing existing-- datasets into an AcidState.groupUpdates::UpdateEventevent=>AcidState(EventStateevent)->[event]->IO()groupUpdatesacidStateevents=goeventswherego[]=return()go[x]=void$updateacidStatexgo(x:xs)=scheduleUpdateacidStatex>>goxs-- | 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.update::UpdateEventevent=>AcidState(EventStateevent)->event->IO(EventResultevent)updateacidStateevent=takeMVar=<<scheduleUpdateacidStateevent-- | Same as 'update' but lifted into any monad capable of doing IO.update'::(UpdateEventevent,MonadIOm)=>AcidState(EventStateevent)->event->m(EventResultevent)update'acidStateevent=liftIO(updateacidStateevent)-- | Issue a Query event and wait for its result. Events may be issued in parallel.query::QueryEventevent=>AcidState(EventStateevent)->event->IO(EventResultevent)query=_query-- Redirection to make Haddock happy.-- | Same as 'query' but lifted into any monad capable of doing IO.query'::(QueryEventevent,MonadIOm)=>AcidState(EventStateevent)->event->m(EventResultevent)query'acidStateevent=liftIO(queryacidStateevent)mkAnyState::Typeable1sub_st=>sub_stst->AnyStatestmkAnyState=AnyStatedowncast::Typeable1sub=>AcidStatest->substdowncastAcidState{acidSubState=AnyStatesub}=rwherer=casegcast1(Justsub)ofJust(Justx)->x_->error$"Data.Acid: Invalid subtype cast: "++show(typeOf1sub)++" -> "++show(typeOf1r)