| 
48 | 48 | -- - The ChainDB is used to create 'Follower's (which in turn contain  | 
49 | 49 | --   'Iterator's).  | 
50 | 50 | --  | 
51 |  | --- These resources must eventually be freed.  | 
 | 51 | +-- These resources must eventually be freed. See function  | 
 | 52 | +-- 'Ouroboros.Consensus.Node.runWith' for an example of an approach  | 
 | 53 | +-- taken to resource management using a resource registry.  | 
52 | 54 | --  | 
53 |  | --- The 'runWith' function in Consensus spawns a resource registry  | 
54 |  | --- (which we will refer to as __the consensus registry__) that will include  | 
55 |  | --- the ChainDB as one of its resources. When the Consensus layer is  | 
56 |  | --- shut down, the consensus resource registry will exit the scope of  | 
57 |  | --- the 'withRegistry' function. This causes all resources allocated  | 
58 |  | --- in the registry —including the ChainDB— to be closed.  | 
59 |  | ---  | 
60 |  | --- The resources mentioned above are created by clients of the ChainDB  | 
61 |  | --- databases (LedgerDB, VolatileDB, and ImmutableDB), not by the  | 
62 |  | --- databases themselves. For example, chain selection opens a  | 
63 |  | --- forker using the LedgerDB. Crucially, this means that clients creating  | 
64 |  | --- these resources are instantiated after the ChainDB.  | 
65 |  | ---  | 
66 |  | --- We rely on a specific sequence of events for this design to be correct:  | 
67 |  | ---  | 
68 |  | --- - The ChainDB is only closed by exiting the scope of the consensus  | 
69 |  | ---   resource registry.  | 
70 |  | ---  | 
71 |  | --- - If a client creates resources tied to any of the  | 
72 |  | ---   aforementioned databases and is forked into a separate thread,  | 
73 |  | ---   that thread is linked to the consensus registry. Because resources  | 
74 |  | ---   in a registry are deallocated in reverse order of allocation, any  | 
75 |  | ---   resources created by such threads will be deallocated before the  | 
76 |  | ---   ChainDB is closed, ensuring proper cleanup.  | 
77 |  | ---  | 
78 |  | --- Currently, we have two distinct approaches to resource management  | 
79 |  | --- and database closure:  | 
80 |  | ---  | 
81 |  | --- - In the LedgerDB, closing the database does not close any resources  | 
82 |  | ---   created by its clients. We rely on the resource registry to deallocate  | 
83 |  | ---   these resources before the LedgerDB is closed. However, after closing  | 
84 |  | ---   the LedgerDB, the only permitted action on these resources is to free them.  | 
85 |  | ---   See 'ldbForkers'.  | 
86 |  | ---  | 
87 |  | --- - In the ChainDB, closing the database also closes all followers and  | 
88 |  | ---   iterators.  | 
89 |  | ---  | 
90 |  | --- TODO: Ideally, the ChainDB and LedgerDB should follow a consistent  | 
91 |  | --- approach to resource deallocation.  | 
92 | 55 | module Ouroboros.Consensus.Storage.ChainDB  | 
93 | 56 |   ( module Ouroboros.Consensus.Storage.ChainDB.API  | 
94 | 57 |   , module Ouroboros.Consensus.Storage.ChainDB.Impl  | 
 | 
0 commit comments