|
113 | 113 | ]; |
114 | 114 | }; |
115 | 115 |
|
| 116 | + # Opt a leios node OUT of the daily recycle below. |
| 117 | + nodeNoRecycle.systemd.services.cardano-node.serviceConfig = { |
| 118 | + RuntimeMaxSec = mkForce "infinity"; |
| 119 | + RuntimeRandomizedExtraSec = mkForce 0; |
| 120 | + }; |
| 121 | + |
116 | 122 | node-leios = |
117 | 123 | # Ouroboros leios makes leios prototype packages available through its cardano-node-leios input |
118 | 124 | mkCustomNode "cardano-node-leios.inputs.cardano-node-leios" |
|
147 | 153 | "ChainDB.AddBlockEvent.AddBlockValidation".severity = "Info"; |
148 | 154 | }; |
149 | 155 | }; |
| 156 | + |
| 157 | + # Temporary mitigation for the under-investigation leios cardano-node |
| 158 | + # heap leak: recycle the service ~daily so memory can't grow unbounded |
| 159 | + # between deploys. RuntimeMaxSec caps runtime; RuntimeRandomizedExtraSec |
| 160 | + # adds 0..N jitter so the fleet doesn't restart in lockstep (thundering |
| 161 | + # herd). Window 20-24h (<= 1 day). Restart=always (cardano-parts) brings |
| 162 | + # the node back; TimeoutStopSec=600 leaves room for a clean shutdown. |
| 163 | + # Analysis/observer nodes opt out via nodeNoRecycle. Remove once the |
| 164 | + # leak is fixed. |
| 165 | + systemd.services.cardano-node.serviceConfig = { |
| 166 | + RuntimeMaxSec = 20 * 3600; |
| 167 | + RuntimeRandomizedExtraSec = 4 * 3600; |
| 168 | + }; |
150 | 169 | }; |
151 | 170 |
|
| 171 | + # Same as node-leios, but the cardano-node binary is rebuilt with |
| 172 | + # info-table-provenance (IPE) flags for low-overhead `+RTS -hi` profiling. |
| 173 | + # node-leios-ipe = { |
| 174 | + # imports = [ |
| 175 | + # node-leios |
| 176 | + # nodeNoRecycle # profiling build: let the heap grow for leak analysis |
| 177 | + # { |
| 178 | + # cardano-parts.perNode.pkgs.cardano-node = lib.mkOverride 40 ( |
| 179 | + # (inputs.cardano-node-leios.inputs.cardano-node-leios.project.x86_64-linux.appendModule { |
| 180 | + # modules = [{ |
| 181 | + # ghcOptions = ["-finfo-table-map" "-fdistinct-constructor-tables"]; |
| 182 | + # packages.plutus-core.components.library.ghcOptions = ["-finfo-table-map" "-fdistinct-constructor-tables"]; |
| 183 | + # }]; |
| 184 | + # }).exes.cardano-node |
| 185 | + # ); |
| 186 | + # } |
| 187 | + # ]; |
| 188 | + # }; |
| 189 | + |
| 190 | + # Same as node-leios-ipe, but the node is ALSO built with the ghc-debug |
| 191 | + # stub, so its live heap can be snapshotted on demand for offline retainer |
| 192 | + # analysis (to find what retains the growing ARR_WORDS / STACK closures the |
| 193 | + # -hi profile can only name, not attribute). |
| 194 | + # |
| 195 | + # `+RTS -hi` heap profiling comes along for free and is enabled below: |
| 196 | + # one node run yields BOTH the continuous -hi eventlog and on-demand |
| 197 | + # ghc-debug snapshots. |
| 198 | + node-leios-ghc-debug = { |
| 199 | + imports = [ |
| 200 | + node-leios |
| 201 | + nodeNoRecycle # ghc-debug build: let the heap grow for leak analysis |
| 202 | + { |
| 203 | + cardano-parts.perNode.pkgs.cardano-node = lib.mkOverride 40 |
| 204 | + inputs.cardano-node-leios-ghc-debug.packages.x86_64-linux.cardano-node-ghc-debug; |
| 205 | + |
| 206 | + # The ghc-debug stub serves here; the snapshot client reads the same |
| 207 | + # path. /run/cardano-node is the node's RuntimeDirectory -- writable |
| 208 | + # by the cardano-node user and ephemeral across restarts. |
| 209 | + systemd.services.cardano-node.environment.GHC_DEBUG_SOCKET = |
| 210 | + "/run/cardano-node/ghc-debug.socket"; |
| 211 | + |
| 212 | + # IPE "free extra": continuous low-overhead info-table (-hi) heap |
| 213 | + # profile written to the eventlog (`eventlog` -> -l, `space-info` -> |
| 214 | + # -hi). `-i30` keeps the heap census cheap on a large heap; the 0.1s |
| 215 | + # default would be far too aggressive. rts_flags_override appends, so |
| 216 | + # the compiled-in -N2/-A16m/etc. are preserved. |
| 217 | + services.cardano-node = { |
| 218 | + eventlog = true; |
| 219 | + profiling = "space-info"; |
| 220 | + rts_flags_override = ["-i30"]; |
| 221 | + }; |
| 222 | + |
| 223 | + # Headless snapshot client on the host PATH. Capture EARLY (moderate |
| 224 | + # heap), NOT at the OOM ceiling -- a snapshot is ~heap-sized and |
| 225 | + # pauses the node for its duration: |
| 226 | + # cardano-ghc-debug-snapshot \ |
| 227 | + # heap.snapshot \ |
| 228 | + # "$GHC_DEBUG_SOCKET" |
| 229 | + environment.systemPackages = [ |
| 230 | + inputs.cardano-node-leios-ghc-debug.packages.x86_64-linux.cardano-ghc-debug-snapshot |
| 231 | + ]; |
| 232 | + } |
| 233 | + ]; |
| 234 | + }; |
| 235 | + |
152 | 236 | eRel = relList: { |
153 | 237 | imports = [ |
154 | 238 | inputs.cardano-parts.nixosModules.profile-cardano-node-topology |
|
183 | 267 | leiosRel = {imports = [rel];}; |
184 | 268 |
|
185 | 269 | leiosCentrifuge.imports = [ |
| 270 | + nodeNoRecycle |
186 | 271 | nixosModules.cardano-tx-centrifuge |
187 | 272 | nixosModules.profile-leios-tx-centrifuge |
188 | 273 | { |
|
1045 | 1130 | # Remove `ccMon` until governance works in Dijkstra era |
1046 | 1131 | # leios1-bp-a-1 = {imports = [eu-central-1 c8id-large (ebs 80) (group "leios1") node-leios leiosBp ccMon];}; |
1047 | 1132 | leios1-bp-a-1 = {imports = [eu-central-1 c8id-large (ebs 80) (group "leios1") node-leios leiosBp];}; |
1048 | | - leios1-rel-a-1 = {imports = [eu-central-1 m8id-xlarge (ebs 80) (nodeRamPct 70) (group "leios1") node-leios leiosRel leiosFilesNginx (eRel ["leios2-rel-b-1" "leios3-rel-c-1"])];}; |
| 1133 | + # nodeNoRecycle: centrifuge load target — stays up to receive load; recycle manually when load is off. |
| 1134 | + leios1-rel-a-1 = {imports = [eu-central-1 m8id-xlarge (ebs 80) (nodeRamPct 70) (group "leios1") node-leios leiosRel leiosFilesNginx nodeNoRecycle (eRel ["leios2-rel-b-1" "leios3-rel-c-1"])];}; |
1049 | 1135 | leios1-rel-a-2 = {imports = [eu-central-1 c8id-xlarge (ebs 80) (nodeRamPct 70) (group "leios1") node-leios leiosRel (eRel ["leios2-rel-b-2" "leios3-rel-c-2"])];}; |
1050 | 1136 | leios1-rel-a-3 = {imports = [eu-central-1 c8id-xlarge (ebs 80) (nodeRamPct 70) (group "leios1") node-leios leiosRel (eRel ["leios2-rel-b-3" "leios3-rel-c-3"])];}; |
1051 | 1137 | leios1-dbsync-a-1 = {imports = [eu-central-1 c8id-2xlarge (ebs 250) (group "leios1") node-leios dbsync-leios smash dbsyncPub (openFwTcp 5432)];}; |
|
1060 | 1146 | leios3-bp-c-1 = {imports = [us-east-2 c8id-large (ebs 80) (group "leios3") node-leios leiosBp];}; |
1061 | 1147 | leios3-rel-c-1 = {imports = [us-east-2 m8id-xlarge (ebs 80) (nodeRamPct 70) (group "leios3") node-leios leiosRel leiosFilesNginx (eRel ["leios1-rel-a-1" "leios2-rel-b-1"])];}; |
1062 | 1148 | leios3-rel-c-2 = {imports = [us-east-2 c8id-xlarge (ebs 80) (nodeRamPct 70) (group "leios3") node-leios leiosRel (eRel ["leios1-rel-a-2" "leios2-rel-b-2"])];}; |
1063 | | - leios3-rel-c-3 = {imports = [us-east-2 c8id-xlarge (ebs 80) (nodeRamPct 70) (group "leios3") node-leios leiosRel (eRel ["leios1-rel-a-3" "leios2-rel-b-3"])];}; |
| 1149 | + leios3-rel-c-3 = {imports = [us-east-2 c8id-xlarge (ebs 80) (nodeRamPct 70) (group "leios3") node-leios-ghc-debug leiosRel (eRel ["leios1-rel-a-3" "leios2-rel-b-3"])];}; |
1064 | 1150 | # --------------------------------------------------------------------------------------------------------- |
1065 | 1151 | # |
1066 | 1152 | # --------------------------------------------------------------------------------------------------------- |
|
0 commit comments