Skip to content

refactor(core): Phase 5 — MonitoringState machine and lifecycle decoupling (#1408)#1420

Merged
shm11C3 merged 1 commit into
developfrom
refactor/1408-phase-5-monitoring-state
Apr 30, 2026
Merged

refactor(core): Phase 5 — MonitoringState machine and lifecycle decoupling (#1408)#1420
shm11C3 merged 1 commit into
developfrom
refactor/1408-phase-5-monitoring-state

Conversation

@shm11C3

@shm11C3 shm11C3 commented Apr 30, 2026

Copy link
Copy Markdown
Owner

Closes #1408. Part of #1402 (Epic).

Summary

  • Add core::monitoring::MonitoringState (Running / Paused / Stopped) with explicit transitions and exhaustive unit tests.
  • Move start/stop wiring out of the inline on_window_event handler into src-tauri/src/lifecycle.rs. The process lifetime is no longer tied to the main window's CloseRequested event.
  • Add a quit_app Tauri command. lifecycle::request_quit transitions the state machine to Stopped, drains workers, then app.exit(0).
  • ArchiveController writes a final summary on shutdown so samples accumulated since the last 60-second tick are not lost on Quit (DoD "DB writes flushed").

User-visible behavior

Unchanged in this phase. Closing the window still quits the app by default. The new "hide window, keep monitoring" path is gated by the env var HARDVIZ_CLOSE_TO_BACKGROUND=1. The persisted setting + tray UX that flip the default ship with #1275 / Phase 6.

Path note

The #1408 issue body says `src-tauri/src/app/lifecycle.rs`, but #1402's 2026-04-30 changelog supersedes it ("`app::lifecycle` → `lifecycle`"). Following the parent epic — `src-tauri/src/lifecycle.rs` directly. `src-tauri/src/app/startup.rs` (DB startup error dialog) is unrelated and stays as-is.

Layout

  • core/src/monitoring/state.rsMonitoringState with pause / resume / stop. Same-state transitions and any transition out of Stopped are rejected with InvalidTransition. Pure Rust, no Tauri runtime needed.
  • src-tauri/src/lifecycle.rson_close_requested, handle_close_request, request_quit, should_close_to_background.
  • src-tauri/src/workers/mod.rsWorkersState gains a monitoring_state: Mutex<MonitoringState> field, colocated with the worker handles so the lifecycle module locks once on quit.
  • src-tauri/src/commands/system.rsquit_app command delegates to lifecycle::request_quit. Reachable via the generated bindings; Phase 6's tray will be the first user-facing caller.
  • core/src/persistence/archive.rsArchiveTracker gains a dirty flag; the spawn loop runs a final write_archive on shutdown signal when dirty.

Tests

  • 17 new state-machine tests cover the full (from, to) grid plus the InvalidTransition Display and per-method coverage. Runnable via cargo test -p hwviz-core without a Tauri runtime.
  • lifecycle::is_truthy parser tests (no env-var mutation, parallel-safe).
  • 2 new ArchiveTracker tests (fresh_tracker_is_not_dirty, ingest_marks_tracker_dirty).
  • All workspace tests pass: 153 in `hwviz-core`, 140 in `hardware_visualizer`.

Out of scope (per #1408)

Test plan

  • cargo tauri-fmt -- --check
  • cargo tauri-lint
  • cargo test --workspace --lib --bins -- --test-threads=1 (the adl_diagnostic example fails to build on macOS; this is pre-existing on develop and unrelated)
  • npm run lint
  • npm run test
  • Bindings regenerated by running the binary (only quitApp added).
  • Manual: launch with HARDVIZ_CLOSE_TO_BACKGROUND=1, close the window, verify the process keeps running and the collector keeps polling. Calling commands.quitApp() from devtools must terminate cleanly with a final archive row written.
  • Manual: launch without the env var, close the window, confirm the historical quit-on-close behavior is preserved.

Summary by CodeRabbit

  • New Features

    • Added monitoring state management with pause, resume, and stop capabilities for sensor collection
    • Window close behavior is now configurable—minimize to background or fully quit the app
    • New explicit quit command for app termination
  • Chores

    • Refactored module structure to support lifecycle management and monitoring state tracking

…pling

Closes #1408.

Introduce `core::monitoring::MonitoringState` (Running / Paused /
Stopped) and move the close/quit decision out of the inline
`on_window_event` handler into `src-tauri/src/lifecycle.rs`. The
process lifetime is no longer tied to the main window's
`CloseRequested` event — that path is reached only through an
explicit Quit action, which the lifecycle module owns.

Default user-visible behavior is unchanged: closing the window still
quits the app. The new "hide window, keep monitoring" path is gated
by the env var `HARDVIZ_CLOSE_TO_BACKGROUND=1`. The persisted setting
and tray UX that flip this default ship with #1275 / Phase 6.

Layout
- `core/src/monitoring/state.rs` — `MonitoringState` with explicit
  `pause` / `resume` / `stop` transitions. Same-state and post-
  `Stopped` transitions are rejected with `InvalidTransition`. Pure
  Rust, runnable via `cargo test -p hwviz-core` without a Tauri
  runtime; covers the full transition grid.
- `src-tauri/src/lifecycle.rs` — `on_close_requested`,
  `handle_close_request`, `request_quit`, plus
  `should_close_to_background`. The close handler dispatches based on
  the env var; `request_quit` transitions the state to `Stopped`,
  drains workers, then `app.exit(0)`.
- `src-tauri/src/workers/mod.rs` — `WorkersState` gains a
  `monitoring_state: Mutex<MonitoringState>` field, colocated with
  the worker handles so the lifecycle module locks once on quit.
- `src-tauri/src/commands/system.rs` — new `quit_app` Tauri command
  delegates to `lifecycle::request_quit`. Reachable from the
  generated bindings; Phase 6's tray will be the first user-facing
  caller.

Persistence flush on Quit
- `ArchiveController` now writes a final summary on shutdown when
  there are unwritten samples (tracked via a `dirty` flag on
  `ArchiveTracker`). Without this, samples accumulated since the
  last 60-second tick were lost on Quit. Satisfies the Phase 5 DoD
  "DB writes flushed".

Out of scope (per #1408): tray UI (Phase 6); the user-facing "close
to tray" setting and first-run dialog (#1275). The Run / Pause /
Resume runtime hookup and frontend rendering pause when hidden are
both #1275 territory — Phase 5 only ships the state machine and the
quit path.
Copilot AI review requested due to automatic review settings April 30, 2026 03:37
@coderabbitai

coderabbitai Bot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR introduces a MonitoringState lifecycle state machine in the core crate with Running/Paused/Stopped transitions, decouples app lifecycle from window close events via a new lifecycle module, adds a graceful quit_app command, and tracks data dirty state in archive persistence for conditional final writes.

Changes

Cohort / File(s) Summary
Core monitoring state machine
core/src/lib.rs, core/src/monitoring/mod.rs, core/src/monitoring/state.rs
Replaces inline empty monitoring module with external module declaration. New MonitoringState enum (Running, Paused, Stopped) with predicate helpers (is_running, is_paused, is_stopped), transition methods (pause, resume, stop), and InvalidTransition error type. Validates state transitions (no no-op transitions, no transitions from Stopped) with comprehensive unit tests.
Archive persistence dirty tracking
core/src/persistence/archive.rs
Adds dirty boolean flag to ArchiveTracker to track ingested data since last write. Updates write_archive() to accept &mut self and clear dirty flag on successful write. Conditional final write during shutdown when dirty.
Tauri lifecycle decoupling
src-tauri/src/lib.rs, src-tauri/src/lifecycle.rs, src-tauri/src/commands/system.rs
Prevents default CloseRequested behavior and routes to new lifecycle::on_close_requested(window). Adds quit_app command that delegates to lifecycle::request_quit(app_handle). New lifecycle module reads HARDVIZ_CLOSE_TO_BACKGROUND env var to toggle between hiding window (background mode) or clean shutdown (monitoring stopped, workers terminated, app exits).
Workers state extension
src-tauri/src/workers/mod.rs
Adds monitoring_state: Mutex<MonitoringState> field to WorkersState to track sensor collection lifecycle phase.
Frontend command binding
src/rspc/bindings.ts
Adds exported quitApp() command to invoke backend quit_app for explicit process termination.

Sequence Diagram

sequenceDiagram
    actor User
    participant Frontend
    participant Tauri App
    participant Lifecycle
    participant Workers
    participant Core

    User->>Frontend: Close window
    Frontend->>Tauri App: CloseRequested event
    Tauri App->>Lifecycle: on_close_requested(window)
    
    alt HARDVIZ_CLOSE_TO_BACKGROUND enabled
        Lifecycle->>Frontend: Hide window
        Note over Workers,Core: Background monitoring continues
    else Default: Clean shutdown
        Lifecycle->>Core: Stop MonitoringState
        Lifecycle->>Workers: terminate_all()
        Workers->>Core: Flush persistence
        Workers->>Tauri App: app.exit(0)
    end

    User->>Frontend: Click quit button
    Frontend->>Tauri App: quit_app command
    Tauri App->>Lifecycle: request_quit(app_handle)
    Lifecycle->>Core: Stop MonitoringState
    Lifecycle->>Workers: terminate_all()
    Workers->>Core: Flush persistence
    Workers->>Tauri App: app.exit(0)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Suggested labels

rust, frontend

Poem

🐰 A state machine hops through Running, Paused, Stopped with care,
No transitions from the end—the rabbit's rules are fair!
Windows hide while work goes on, or quit flows clean and true,
Dirty flags and graceful shutdowns—lifecycle made anew! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: introducing MonitoringState machine and decoupling lifecycle from window close events.
Description check ✅ Passed The PR description comprehensively covers summary, related issues, type of change, test plan with checkmarks, and all required sections from the template.
Linked Issues check ✅ Passed All coding objectives from #1408 are fully met: MonitoringState machine with transitions [#1408], lifecycle decoupling from window close [#1408], quit_app command with clean shutdown [#1408], and exhaustive unit tests [#1408].
Out of Scope Changes check ✅ Passed All changes align with #1408 scope: MonitoringState implementation, lifecycle wiring, quit_app command, ArchiveTracker flushing, and test coverage. No unrelated changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/1408-phase-5-monitoring-state

Review rate limit: 3/5 reviews remaining, refill in 15 minutes and 54 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added rust Pull requests that update Rust code frontend labels Apr 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 97.43% (🎯 60%) 1025 / 1052
🔵 Statements 96.88% (🎯 60%) 1088 / 1123
🔵 Functions 97% (🎯 60%) 259 / 267
🔵 Branches 89.84% (🎯 60%) 345 / 384
File CoverageNo changed files found.
Generated in workflow #2832 for commit 77f9e81 by the Vitest Coverage Report Action

@shm11C3 shm11C3 enabled auto-merge (squash) April 30, 2026 03:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements Phase 5 of the Core/App split by introducing a Tauri-independent MonitoringState state machine in hwviz-core, decoupling app process lifetime from the main window close event via a new lifecycle module, and adding an explicit “Quit” command that performs an ordered shutdown (including a final archive flush).

Changes:

  • Add hwviz_core::monitoring::MonitoringState with explicit transitions and unit tests.
  • Move window close handling into src-tauri/src/lifecycle.rs, adding a quit_app command for explicit shutdown and gating “close-to-background” via HARDVIZ_CLOSE_TO_BACKGROUND.
  • Update persistence archive worker to perform a shutdown-time final write when new samples arrived since the last tick.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/rspc/bindings.ts Regenerated tauri-specta bindings to include quitApp().
src-tauri/src/workers/mod.rs Adds monitoring_state: Mutex<MonitoringState> to WorkersState for lifecycle-owned transitions.
src-tauri/src/lifecycle.rs New lifecycle module handling CloseRequested policy and explicit quit ordering.
src-tauri/src/lib.rs Wires lifecycle close handler and registers the new quit_app command.
src-tauri/src/commands/system.rs Adds quit_app Tauri command delegating to lifecycle::request_quit.
core/src/persistence/archive.rs Adds dirty tracking and shutdown-time final archive write path.
core/src/monitoring/state.rs Implements MonitoringState + InvalidTransition with exhaustive tests.
core/src/monitoring/mod.rs Exposes the monitoring module and re-exports state types.
core/src/lib.rs Switches monitoring from a placeholder module to a real module.

Comment thread core/src/persistence/archive.rs
Comment thread core/src/persistence/archive.rs
@github-actions

Copy link
Copy Markdown
Contributor

Rust Backend Coverage Report

Coverage Details
Filename                                                   Regions    Missed Regions     Cover   Functions  Missed Functions  Executed       Lines      Missed Lines     Cover    Branches   Missed Branches     Cover
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
core/src/collector/history.rs                                  710               154    78.31%          47                15    68.09%         373                89    76.14%           0                 0         -
core/src/collector/sampling.rs                                 445               178    60.00%          45                20    55.56%         283               117    58.66%           0                 0         -
core/src/collector/system_monitor.rs                            72                72     0.00%           4                 4     0.00%          39                39     0.00%           0                 0         -
core/src/enums/hardware.rs                                      14                14     0.00%           2                 2     0.00%          12                12     0.00%           0                 0         -
core/src/event_bus.rs                                          167                 3    98.20%          19                 1    94.74%         108                 3    97.22%           0                 0         -
core/src/infrastructure/database/db.rs                          28                28     0.00%           4                 4     0.00%          22                22     0.00%           0                 0         -
core/src/infrastructure/database/gpu_archive.rs                 51                51     0.00%           4                 4     0.00%          18                18     0.00%           0                 0         -
core/src/infrastructure/database/hardware_archive.rs            41                41     0.00%           4                 4     0.00%          18                18     0.00%           0                 0         -
core/src/infrastructure/database/process_stats.rs               41                41     0.00%           4                 4     0.00%          27                27     0.00%           0                 0         -
core/src/infrastructure/providers/linux/dmidecode.rs           229                15    93.45%          16                 3    81.25%         319                14    95.61%           0                 0         -
core/src/infrastructure/providers/linux/drm_sys.rs             205               156    23.90%          21                14    33.33%         126                93    26.19%           0                 0         -
core/src/infrastructure/providers/linux/hwmon.rs               119                94    21.01%           8                 6    25.00%          68                56    17.65%           0                 0         -
core/src/infrastructure/providers/linux/kernel.rs              165                22    86.67%          19                 2    89.47%         161                 8    95.03%           0                 0         -
core/src/infrastructure/providers/linux/lspci.rs                83                20    75.90%           8                 2    75.00%          50                11    78.00%           0                 0         -
core/src/infrastructure/providers/linux/net_sys.rs             171               171     0.00%          13                13     0.00%          93                93     0.00%           0                 0         -
core/src/infrastructure/providers/linux/procfs.rs              261                24    90.80%          25                 3    88.00%         222                19    91.44%           0                 0         -
core/src/infrastructure/providers/sysinfo_provider.rs           54                54     0.00%           2                 2     0.00%          45                45     0.00%           0                 0         -
core/src/monitoring/state.rs                                   230                 0   100.00%          28                 0   100.00%         155                 0   100.00%           0                 0         -
core/src/persistence/archive.rs                                897               151    83.17%          61                 8    86.89%         581                89    84.68%           0                 0         -
core/src/persistence/preflight.rs                              297                 5    98.32%          27                 0   100.00%         190                 6    96.84%           0                 0         -
core/src/platform/factory.rs                                    18                18     0.00%           4                 4     0.00%          15                15     0.00%           0                 0         -
core/src/platform/linux/cache.rs                                53                53     0.00%           4                 4     0.00%          38                38     0.00%           0                 0         -
core/src/platform/linux/gpu.rs                                 137               137     0.00%          14                14     0.00%          98                98     0.00%           0                 0         -
core/src/platform/linux/memory.rs                               43                43     0.00%           6                 6     0.00%          41                41     0.00%           0                 0         -
core/src/platform/linux/mod.rs                                  33                33     0.00%          11                11     0.00%          69                69     0.00%           0                 0         -
core/src/platform/linux/network.rs                               4                 4     0.00%           1                 1     0.00%           4                 4     0.00%           0                 0         -
core/src/settings/hardware_archive.rs                           36                 0   100.00%           4                 0   100.00%          26                 0   100.00%           0                 0         -
core/src/settings/mod.rs                                       328                37    88.72%          26                 8    69.23%         168                19    88.69%           0                 0         -
core/src/utils/formatter.rs                                    195                 8    95.90%          16                 0   100.00%         160                12    92.50%           0                 0         -
core/src/utils/ip.rs                                            65                 0   100.00%           5                 0   100.00%          33                 0   100.00%           0                 0         -
core/src/utils/rounding.rs                                      68                 0   100.00%           7                 0   100.00%          41                 0   100.00%           0                 0         -
src-tauri/src/_tests/commands/background_image_test.rs          39                 0   100.00%           6                 0   100.00%          21                 0   100.00%           0                 0         -
src-tauri/src/_tests/commands/settings_test.rs                 219                 0   100.00%          18                 0   100.00%         162                 0   100.00%           0                 0         -
src-tauri/src/adapters/window.rs                               254                69    72.83%          21                 8    61.90%         195                47    75.90%           0                 0         -
src-tauri/src/app/startup.rs                                   188                87    53.72%          10                 3    70.00%         114                58    49.12%           0                 0         -
src-tauri/src/commands/background_image.rs                      22                 7    68.18%          11                 5    54.55%          19                 7    63.16%           0                 0         -
src-tauri/src/commands/hardware.rs                              62                62     0.00%          20                20     0.00%          68                68     0.00%           0                 0         -
src-tauri/src/commands/settings.rs                             578               578     0.00%         102               102     0.00%         497               497     0.00%           0                 0         -
src-tauri/src/commands/system.rs                                12                12     0.00%           6                 6     0.00%          10                10     0.00%           0                 0         -
src-tauri/src/commands/ui.rs                                    17                17     0.00%           2                 2     0.00%          13                13     0.00%           0                 0         -
src-tauri/src/commands/updater.rs                               97                97     0.00%          15                15     0.00%          66                66     0.00%           0                 0         -
src-tauri/src/enums/error.rs                                   115                10    91.30%           9                 1    88.89%          99                10    89.90%           0                 0         -
src-tauri/src/enums/hardware.rs                                194                 7    96.39%          16                 1    93.75%         120                 6    95.00%           0                 0         -
src-tauri/src/enums/settings.rs                                425                16    96.24%          26                 2    92.31%         289                10    96.54%           0                 0         -
src-tauri/src/infrastructure/database/migration.rs              66                 1    98.48%          10                 0   100.00%          86                 0   100.00%           0                 0         -
src-tauri/src/lib.rs                                           188               188     0.00%           5                 5     0.00%         110               110     0.00%           0                 0         -
src-tauri/src/lifecycle.rs                                      94                45    52.13%          11                 7    36.36%          57                34    40.35%           0                 0         -
src-tauri/src/main.rs                                            3                 3     0.00%           1                 1     0.00%           3                 3     0.00%           0                 0         -
src-tauri/src/models/hardware.rs                               375                83    77.87%          31                12    61.29%         275               100    63.64%           0                 0         -
src-tauri/src/models/hardware_archive.rs                         8                 0   100.00%           2                 0   100.00%          10                 0   100.00%           0                 0         -
src-tauri/src/models/settings.rs                               283                 0   100.00%          16                 0   100.00%         246                 0   100.00%           0                 0         -
src-tauri/src/services/background_image_service.rs             165                96    41.82%          16                10    37.50%          93                59    36.56%           0                 0         -
src-tauri/src/services/gpu_service.rs                           56                56     0.00%          11                11     0.00%          43                43     0.00%           0                 0         -
src-tauri/src/services/hardware_service.rs                      85                85     0.00%           4                 4     0.00%          51                51     0.00%           0                 0         -
src-tauri/src/services/language_service.rs                     101                 0   100.00%          18                 0   100.00%          57                 0   100.00%           0                 0         -
src-tauri/src/services/memory_service.rs                        12                12     0.00%           3                 3     0.00%           7                 7     0.00%           0                 0         -
src-tauri/src/services/motherboard_service.rs                   12                12     0.00%           3                 3     0.00%           7                 7     0.00%           0                 0         -
src-tauri/src/services/network_service.rs                       14                14     0.00%           1                 1     0.00%           8                 8     0.00%           0                 0         -
src-tauri/src/services/settings_service.rs                     321               143    55.45%          31                13    58.06%         269               130    51.67%           0                 0         -
src-tauri/src/services/system_service.rs                        22                22     0.00%           2                 2     0.00%          12                12     0.00%           0                 0         -
src-tauri/src/services/ui_service.rs                            45                45     0.00%           8                 8     0.00%          36                36     0.00%           0                 0         -
src-tauri/src/utils/color.rs                                    66                 1    98.48%           4                 0   100.00%          26                 0   100.00%           0                 0         -
src-tauri/src/utils/file.rs                                    224                 5    97.77%          14                 0   100.00%         144                 4    97.22%           0                 0         -
src-tauri/src/utils/formatter.rs                                55                 0   100.00%           5                 0   100.00%          39                 0   100.00%           0                 0         -
src-tauri/src/utils/logger.rs                                   71                71     0.00%           1                 1     0.00%          38                38     0.00%           0                 0         -
src-tauri/src/utils/tauri.rs                                   138                 0   100.00%          17                 0   100.00%          82                 0   100.00%           0                 0         -
src-tauri/src/workers/mod.rs                                    32                32     0.00%           2                 2     0.00%          20                20     0.00%           0                 0         -
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TOTAL                                                         9918              3503    64.68%         937               407    56.56%        6995              2529    63.85%           0                 0         -

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
core/src/persistence/archive.rs (1)

318-355: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep dirty set until the archive write succeeds.

Clearing the flag at the start means a partial DB failure logs an error but still looks “clean,” so the shutdown flush at lines 118-125 is skipped and the last batch can be lost.

🔧 Suggested fix
 async fn write_archive(&mut self) {
   use crate::infrastructure::database;
   use crate::log_error;
 
-  self.dirty = false;
+  let mut write_succeeded = true;
 
   let cpu = StatsCalculator::compute_stats(self.cpu_history.iter().copied());
   let memory = StatsCalculator::compute_stats(self.memory_history.iter().copied());
 
   if let Err(e) = database::hardware_archive::insert(cpu, memory).await {
+    write_succeeded = false;
     log_error!(
       "Failed to insert hardware archive data",
       "persistence::archive::write_archive",
       Some(e.to_string())
     );
   }
@@
   for gpu in self.collect_gpu_data() {
     if let Err(e) = database::gpu_archive::insert(gpu).await {
+      write_succeeded = false;
       log_error!(
         "Failed to insert GPU hardware archive data",
         "persistence::archive::write_archive",
         Some(e.to_string())
       );
@@
   if !process_stats.is_empty()
     && let Err(e) = database::process_stats::insert(process_stats).await
   {
+    write_succeeded = false;
     log_error!(
       "Failed to insert process stats data",
       "persistence::archive::write_archive",
       Some(e.to_string())
     );
   }
+
+  if write_succeeded {
+    self.dirty = false;
+  }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/src/persistence/archive.rs` around lines 318 - 355, The method
write_archive clears self.dirty immediately, causing partial DB failures to
leave state marked clean; change it so self.dirty remains true until all
database inserts succeed: move clearing of self.dirty to after all insert
operations complete successfully (e.g., compute cpu/memory stats, call
database::hardware_archive::insert, loop over collect_gpu_data() calling
database::gpu_archive::insert, and call database::process_stats::insert for
collect_process_stats()), and if any insert returns Err set (or keep) self.dirty
= true and log the error; only set self.dirty = false when every insert returned
Ok (or track a success boolean and set false at the end when success is true).
🧹 Nitpick comments (1)
src-tauri/src/lifecycle.rs (1)

80-87: Centralize shutdown state transition to avoid lifecycle inconsistency.

Two callers invoke terminate_all() with inconsistent state management: request_quit() transitions monitoring_state to Stopped before draining workers (lifecycle.rs:85), but restart_app() in system_service.rs drains workers without this transition. While monitoring_state isn't currently read elsewhere, consolidating both the state transition and worker drain into a single helper on WorkersState prevents future code from observing stale state.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/src/lifecycle.rs` around lines 80 - 87, Centralize the shutdown
transition by adding a new helper on WorkersState (e.g., stop_and_terminate_all
or shutdown) that performs the monitoring_state stop() transition under the
existing mutex and then awaits terminate_all(); replace the direct calls in
request_quit() (which currently does ws.monitoring_state.lock().unwrap().stop();
ws.terminate_all().await) and in restart_app() so both call the new WorkersState
helper, ensuring the state transition and worker drain are performed atomically
through the WorkersState API.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@core/src/persistence/archive.rs`:
- Around line 318-355: The method write_archive clears self.dirty immediately,
causing partial DB failures to leave state marked clean; change it so self.dirty
remains true until all database inserts succeed: move clearing of self.dirty to
after all insert operations complete successfully (e.g., compute cpu/memory
stats, call database::hardware_archive::insert, loop over collect_gpu_data()
calling database::gpu_archive::insert, and call database::process_stats::insert
for collect_process_stats()), and if any insert returns Err set (or keep)
self.dirty = true and log the error; only set self.dirty = false when every
insert returned Ok (or track a success boolean and set false at the end when
success is true).

---

Nitpick comments:
In `@src-tauri/src/lifecycle.rs`:
- Around line 80-87: Centralize the shutdown transition by adding a new helper
on WorkersState (e.g., stop_and_terminate_all or shutdown) that performs the
monitoring_state stop() transition under the existing mutex and then awaits
terminate_all(); replace the direct calls in request_quit() (which currently
does ws.monitoring_state.lock().unwrap().stop(); ws.terminate_all().await) and
in restart_app() so both call the new WorkersState helper, ensuring the state
transition and worker drain are performed atomically through the WorkersState
API.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 2260a20f-df69-4c82-9efc-033e857155a4

📥 Commits

Reviewing files that changed from the base of the PR and between b7fdbef and 77f9e81.

📒 Files selected for processing (9)
  • core/src/lib.rs
  • core/src/monitoring/mod.rs
  • core/src/monitoring/state.rs
  • core/src/persistence/archive.rs
  • src-tauri/src/commands/system.rs
  • src-tauri/src/lib.rs
  • src-tauri/src/lifecycle.rs
  • src-tauri/src/workers/mod.rs
  • src/rspc/bindings.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(core): Phase 5 — introduce MonitoringState machine and decouple lifecycle from window close

2 participants