-
Notifications
You must be signed in to change notification settings - Fork 47
feat: better visibility around exiting using log, reason and exitCode #814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughThis change introduces a structured pipeline termination system that tracks why a pipeline stops. It defines a Changes
Sequence DiagramsequenceDiagram
participant Daemon
participant Pipeline as run_pipeline
participant Pull as Pull Quota System
participant Apply as Apply & Flags
participant Signal as Signal Handler
Daemon->>Pipeline: start pipeline execution
activate Pipeline
loop During execution
Pull->>Pull: Check block quota
Pull->>Apply: set_quota_reached(true) if exhausted
Apply->>Apply: QUOTA_REACHED flag set
Apply->>Apply: Detect StopEpochReached error
Apply->>Apply: STOP_EPOCH_REACHED flag set
end
Signal->>Pipeline: Exit signal received
Note over Pipeline: Check stop conditions
alt StopEpochReached flag set
Pipeline->>Pipeline: return StopEpochReached
else QuotaReached flag set
Pipeline->>Pipeline: return QuotaReached
else Exit signal
Pipeline->>Pipeline: return Signal
else Other condition
Pipeline->>Pipeline: return Other
end
Pipeline->>Daemon: PipelineStopReason
deactivate Pipeline
activate Daemon
Daemon->>Daemon: Map reason to exit code
alt exit code == 0
Daemon->>Daemon: return Ok(())
else exit code != 0
Daemon->>Daemon: exit process with code
end
deactivate Daemon
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
src/bin/dolos/daemon.rs (1)
45-45: Consider handling task panic more gracefully.The
.unwrap()will panic if the spawnedrun_pipelinetask itself panics, which could mask the underlying error. Consider usingunwrap_orto provide a fallback stop reason.- let stop_reason = sync.await.unwrap(); + let stop_reason = sync.await.unwrap_or(crate::common::PipelineStopReason::Other);src/sync/pull.rs (1)
176-189: Unreachable fallback arm.The
_ =>arm (lines 185-188) is unreachable becauseshould_quit()only returnstrueforReachedTipandReachedBlockQuota. Consider replacing it withunreachable!()to make the invariant explicit, or removing it entirely since the match is exhaustive for the cases whereshould_quit()is true.PullQuota::ReachedBlockQuota => { info!("sync quota reached: maximum number of blocks has been processed, stopping sync as configured"); set_quota_reached(true); } - _ => { - warn!("quota reached, stopping sync"); - set_quota_reached(true); - } }src/bin/dolos/common.rs (1)
317-328: Consider recursive cleanup for subdirectories.The current implementation only removes files directly in the root directory but doesn't handle subdirectories. If the storage path contains nested directories (e.g.,
wal/,chain/,state/), they won't be removed, and the finalfs::remove_dir(root)on line 325 will fail because the directory won't be empty.Consider using
fs::remove_dir_all(root)for complete cleanup:if root.is_dir() { - for entry_result in fs::read_dir(root)? { - let entry = entry_result?; - let entry_path = entry.path(); - if entry_path.is_file() { - fs::remove_file(&entry_path)?; - } - } - fs::remove_dir(root)?; // Remove the now-empty directory + fs::remove_dir_all(root)?; } else { info!("Path is not a directory, ignoring."); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/bin/dolos/common.rs(2 hunks)src/bin/dolos/daemon.rs(1 hunks)src/bin/dolos/data/summary.rs(1 hunks)src/sync/apply.rs(2 hunks)src/sync/mod.rs(1 hunks)src/sync/pull.rs(4 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
src/bin/dolos/data/summary.rs (2)
src/facade.rs (1)
dolos_core(31-31)src/prelude.rs (1)
config(44-46)
src/bin/dolos/common.rs (1)
src/sync/apply.rs (2)
is_quota_reached(23-25)is_stop_epoch_reached(15-17)
src/bin/dolos/daemon.rs (1)
src/sync/mod.rs (1)
sync(57-87)
src/sync/apply.rs (1)
crates/core/src/facade.rs (1)
roll_forward(119-133)
src/sync/pull.rs (1)
src/sync/apply.rs (1)
set_quota_reached(19-21)
🔇 Additional comments (9)
src/bin/dolos/data/summary.rs (1)
1-3: LGTM!The import reordering is clean and follows Rust conventions by grouping related imports together.
src/sync/mod.rs (1)
34-35: LGTM!Trivial comment rewrap with no functional changes.
src/bin/dolos/daemon.rs (1)
49-61: LGTM!The exit code mapping is clear and aligns with the PR objectives: treating
SignalandStopEpochReachedas successful exits (0), whileQuotaReached(1) andOther(2) are treated as non-successful. Usingstd::process::exit()for non-zero cases is appropriate for daemon termination.src/sync/apply.rs (2)
9-25: LGTM!The global atomic flags with
SeqCstordering provide a simple and correct cross-stage signaling mechanism for the gasket framework. The public API (set_*/is_*functions) cleanly encapsulates the atomic operations.
73-88: LGTM!The differentiated error handling correctly sets the
STOP_EPOCH_REACHEDflag before returningWorkerError::Panic, allowing downstream code to distinguish between a graceful stop-epoch termination and an actual error. The logging for other domain errors provides visibility for debugging.src/sync/pull.rs (2)
44-56: LGTM!The split into
ReachedTipandReachedBlockQuotavariants provides better granularity for understanding termination reasons. Theshould_quit()andon_tip()methods are correctly updated to reflect the new variants.
60-75: LGTM!The
consume_blocksmethod correctly usessaturating_subto prevent underflow and provides informative logging when the quota is exhausted. The state transition toReachedBlockQuotais properly handled.src/bin/dolos/common.rs (2)
265-275: LGTM!The
PipelineStopReasonenum is well-designed with clear doc comments explaining each variant. DerivingDebugandPartialEqis appropriate for logging and testing purposes.
277-310: LGTM!The updated
run_pipelinefunction correctly determines and returns the stop reason. The priority order (checkingis_stop_epoch_reached()beforeis_quota_reached()) is sensible, and the upgraded log levels fromdebugtoinfoimprove operational visibility as intended by the PR.
No offense taken if this is not pretty code. This improves the visibility around debugging and understanding why dolos stops. Also gives better correctness around exit codes. We assume exiting because syncHeight has been reached to be a successful exit reason, otherwise if it's QuotaReached it's not a successful exit.
Summary by CodeRabbit
New Features
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.