Skip to content

Commit b89a04b

Browse files
committed
LedgerDB.V2: factor out utils for getting + duplicating handles
No behavioral change, purely a refactoring
1 parent 71aca5d commit b89a04b

File tree

1 file changed

+43
-21
lines changed
  • ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/LedgerDB

1 file changed

+43
-21
lines changed

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/LedgerDB/V2.hs

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,20 @@ module Ouroboros.Consensus.Storage.LedgerDB.V2 (mkInitDb) where
2020
import Control.Arrow ((>>>))
2121
import qualified Control.Monad as Monad (void, (>=>))
2222
import Control.Monad.Except
23-
import Control.Monad.Trans (lift)
2423
import Control.RAWLock
2524
import qualified Control.RAWLock as RAWLock
2625
import Control.ResourceRegistry
2726
import Control.Tracer
27+
import Data.Foldable (traverse_)
2828
import qualified Data.Foldable as Foldable
2929
import Data.Functor.Contravariant ((>$<))
3030
import Data.Kind (Type)
3131
import Data.Map (Map)
3232
import qualified Data.Map.Strict as Map
3333
import Data.Set (Set)
3434
import qualified Data.Set as Set
35+
import Data.Traversable (for)
36+
import Data.Tuple (Solo (..))
3537
import Data.Void
3638
import Data.Word
3739
import GHC.Generics
@@ -369,17 +371,13 @@ implTryTakeSnapshot ::
369371
implTryTakeSnapshot 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+
556582
acquireAtTarget ::
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

592614
newForkerAtTarget ::
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

607629
newForkerByRollback ::
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.
623645
closeAllForkers ::

0 commit comments

Comments
 (0)