feat(command): real SHUTDOWN [NOSAVE|SAVE] + clean-shutdown AOF data-loss fix (task #27)#314
Conversation
…ul stop Task #27: SHUTDOWN was a stub that always replied "ERR Errors trying to SHUTDOWN. Check logs." and never terminated the process. It is now intercepted at the connection-handler level (same pattern as BGSAVE/ACL) in all three dispatch paths -- handler_single, handler_sharded, handler_monoio: - Parses the optional NOSAVE/SAVE modifier (Redis parity: bare SHUTDOWN saves iff RDB save points are configured; NOSAVE always skips; SAVE always forces). ABORT is rejected (Moon's SHUTDOWN runs synchronously to completion -- there is never an in-progress shutdown to abort); FORCE/NOW are accepted no-ops. - A forced save that fails replies an error and the server stays up: single-shard uses the existing synchronous SAVE path; sharded/monoio use the cooperative per-shard BGSAVE snapshot, polled with a 10s bounded timeout (SHUTDOWN_SAVE_TIMEOUT_MS). - On success, triggers the exact same CancellationToken-driven graceful shutdown sequence already used for SIGTERM (per-shard WAL/AOF flush + fsync across every plane, accept-loop stop, clean connection teardown) instead of reimplementing it. No reply is sent on success -- Redis parity: the client observes the connection close. - ACL category was already admin/dangerous (DNG) in the command registry. Also fixes a real, pre-existing AOF-writer data-loss race surfaced while building the durability test: on first boot the AOF manifest is created on a separate thread from the one that starts accepting connections, and the writer's manifest-wait loop checked cancellation BEFORE attempting the load each iteration. A shutdown landing in that ~50ms window made the writer bail out without ever loading the by-then-current manifest, silently dropping every already-queued Append (reproduced >80% of runs: "AOF writer: cancelled while waiting for manifest" + a 0-byte incr file). Fixed in all three affected writer-loop variants (TopLevel-monoio, PerShard-tokio, PerShard-monoio) by trying the load first. Coverage: tests/shutdown_integration.rs (NOSAVE prompt exit + waitpid status, AOF durability across a SHUTDOWN->restart round trip -- stress tested 25x clean after the writer-task fix, a failed forced SAVE keeps the server up, syntax errors keep the server up) plus a cross-shard durability smoke section in scripts/test-consistency.sh. All four integration tests + 13 new/existing persistence unit tests green; cargo fmt, clippy (default + runtime-tokio feature matrices) clean. author: Tin Dang
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (12)
📝 WalkthroughWalkthroughChangesSHUTDOWN now supports SHUTDOWN and durability
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant ConnectionHandler
participant BGSAVE
participant CancellationToken
Client->>ConnectionHandler: SHUTDOWN SAVE or NOSAVE
ConnectionHandler->>BGSAVE: Start and poll save when required
BGSAVE-->>ConnectionHandler: Completion status
ConnectionHandler->>CancellationToken: Cancel graceful shutdown
ConnectionHandler-->>Client: Close connection without reply
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
…82a6c87be0b # Conflicts: # CHANGELOG.md
Task #27: SHUTDOWN implemented with Redis parity across all three dispatch paths (single/sharded/monoio): NOSAVE/SAVE/FORCE/NOW parsing, bare SHUTDOWN saves iff save points configured, failed forced save replies error and stays up, success reuses the SIGTERM CancellationToken graceful path with no reply (connection closes). ACL category DNG (already present); MULTI-queue fallback fails closed.
Bonus real bug fixed: all three AOF writer manifest-wait loops checked
cancel.is_cancelled()BEFOREAofManifest::load, so a shutdown in the boot-time race window dropped already-queued Appends — silent data loss on a CLEAN shutdown (>80% repro). Fixed load-first in all three; stress-verified 25/25.Verification: new
tests/shutdown_integration.rs(4 real-server tests: NOSAVE waitpid exit, AOF durability across SHUTDOWN→restart, save-failure keeps server up, syntax errors keep server up) 5× green; test-consistency.sh SHUTDOWN section; 13 unit tests; fmt+clippy both matrices clean. Refs task #27.Summary by CodeRabbit
New Features
SHUTDOWN [NOSAVE|SAVE], including case-insensitive options and graceful connection closure.SAVEpersists data before shutdown; failures return an error while keeping the server available.Bug Fixes
Tests