@@ -20,18 +20,20 @@ module Ouroboros.Consensus.Storage.LedgerDB.V2 (mkInitDb) where
2020import Control.Arrow ((>>>) )
2121import qualified Control.Monad as Monad (void , (>=>) )
2222import Control.Monad.Except
23- import Control.Monad.Trans (lift )
2423import Control.RAWLock
2524import qualified Control.RAWLock as RAWLock
2625import Control.ResourceRegistry
2726import Control.Tracer
27+ import Data.Foldable (traverse_ )
2828import qualified Data.Foldable as Foldable
2929import Data.Functor.Contravariant ((>$<) )
3030import Data.Kind (Type )
3131import Data.Map (Map )
3232import qualified Data.Map.Strict as Map
3333import Data.Set (Set )
3434import qualified Data.Set as Set
35+ import Data.Traversable (for )
36+ import Data.Tuple (Solo (.. ))
3537import Data.Void
3638import Data.Word
3739import GHC.Generics
@@ -369,17 +371,13 @@ implTryTakeSnapshot ::
369371implTryTakeSnapshot bss env mTime nrBlocks =
370372 if onDiskShouldTakeSnapshot (ldbSnapshotPolicy env) (uncurry (flip diffTime) <$> mTime) nrBlocks
371373 then do
372- let getStateRef =
373- RAWLock. withReadAccess (ldbOpenHandlesLock env) $ \ LDBLock -> do
374- stateRef <- anchorHandle <$> readTVarIO (ldbSeq env)
375- tables' <- duplicate $ tables stateRef
376- pure stateRef{tables = tables'}
377- bracket getStateRef (close . tables) $
378- Monad. void
379- . takeSnapshot
374+ withStateRef env (MkSolo . anchorHandle) $ \ (MkSolo st) ->
375+ Monad. void $
376+ takeSnapshot
380377 (configCodec . getExtLedgerCfg . ledgerDbCfg $ ldbCfg env)
381378 (LedgerDBSnapshotEvent >$< ldbTracer env)
382379 (ldbHasFS env)
380+ st
383381 Monad. void $
384382 trimSnapshots
385383 (LedgerDBSnapshotEvent >$< ldbTracer env)
@@ -551,8 +549,36 @@ getEnvSTM (LDBHandle varState) f =
551549 Acquiring consistent views
552550-------------------------------------------------------------------------------}
553551
554- -- | This function must hold the 'LDBLock' such that handles are not released
555- -- before they are duplicated.
552+ -- | Get a 'StateRef' from the 'LedgerSeq' in the 'LedgerDBEnv', with the
553+ -- 'LedgerTablesHandle' having been duplicated (such that the original can be
554+ -- closed). The caller is responsible for closing the handle.
555+ --
556+ -- For more flexibility, an arbitrary 'Traversable' of the 'StateRef' can be
557+ -- returned; for the simple use case of getting a single 'StateRef', use @t ~
558+ -- 'Solo'@.
559+ getStateRef ::
560+ (IOLike m , Traversable t ) =>
561+ LedgerDBEnv m l blk ->
562+ (LedgerSeq m l -> t (StateRef m l )) ->
563+ m (t (StateRef m l ))
564+ getStateRef ldbEnv project =
565+ RAWLock. withReadAccess (ldbOpenHandlesLock ldbEnv) $ \ LDBLock -> do
566+ tst <- project <$> readTVarIO (ldbSeq ldbEnv)
567+ for tst $ \ st -> do
568+ tables' <- duplicate $ tables st
569+ pure st{tables = tables'}
570+
571+ -- | Like 'StateRef', but takes care of closing the handle when the given action
572+ -- returns or errors.
573+ withStateRef ::
574+ (IOLike m , Traversable t ) =>
575+ LedgerDBEnv m l blk ->
576+ (LedgerSeq m l -> t (StateRef m l )) ->
577+ (t (StateRef m l ) -> m a ) ->
578+ m a
579+ withStateRef ldbEnv project =
580+ bracket (getStateRef ldbEnv project) (traverse_ (close . tables))
581+
556582acquireAtTarget ::
557583 ( HeaderHash l ~ HeaderHash blk
558584 , IOLike m
@@ -562,11 +588,9 @@ acquireAtTarget ::
562588 ) =>
563589 LedgerDBEnv m l blk ->
564590 Either Word64 (Target (Point blk )) ->
565- LDBLock ->
566591 m (Either GetForkerError (StateRef m l ))
567- acquireAtTarget ldbEnv target _ = runExceptT $ do
568- l <- lift $ readTVarIO (ldbSeq ldbEnv)
569- StateRef st tbs <- case target of
592+ acquireAtTarget ldbEnv target =
593+ getStateRef ldbEnv $ \ l -> case target of
570594 Right VolatileTip -> pure $ currentHandle l
571595 Right ImmutableTip -> pure $ anchorHandle l
572596 Right (SpecificPoint pt) -> do
@@ -586,8 +610,6 @@ acquireAtTarget ldbEnv target _ = runExceptT $ do
586610 , rollbackRequested = n
587611 }
588612 Just l' -> pure $ currentHandle l'
589- tbs' <- lift $ duplicate tbs
590- pure $ StateRef st tbs'
591613
592614newForkerAtTarget ::
593615 ( HeaderHash l ~ HeaderHash blk
@@ -601,8 +623,8 @@ newForkerAtTarget ::
601623 ResourceRegistry m ->
602624 Target (Point blk ) ->
603625 m (Either GetForkerError (Forker m l blk ))
604- newForkerAtTarget h rr pt = getEnv h $ \ ldbEnv@ LedgerDBEnv {ldbOpenHandlesLock = lock} ->
605- RAWLock. withReadAccess lock ( acquireAtTarget ldbEnv (Right pt) ) >>= traverse (newForker h ldbEnv rr)
626+ newForkerAtTarget h rr pt = getEnv h $ \ ldbEnv ->
627+ acquireAtTarget ldbEnv (Right pt) >>= traverse (newForker h ldbEnv rr)
606628
607629newForkerByRollback ::
608630 ( HeaderHash l ~ HeaderHash blk
@@ -616,8 +638,8 @@ newForkerByRollback ::
616638 ResourceRegistry m ->
617639 Word64 ->
618640 m (Either GetForkerError (Forker m l blk ))
619- newForkerByRollback h rr n = getEnv h $ \ ldbEnv@ LedgerDBEnv {ldbOpenHandlesLock = lock} -> do
620- RAWLock. withReadAccess lock ( acquireAtTarget ldbEnv (Left n) ) >>= traverse (newForker h ldbEnv rr)
641+ newForkerByRollback h rr n = getEnv h $ \ ldbEnv ->
642+ acquireAtTarget ldbEnv (Left n) >>= traverse (newForker h ldbEnv rr)
621643
622644-- | Close all open 'Forker's.
623645closeAllForkers ::
0 commit comments