Skip to content

Conversation

@jfro
Copy link
Member

@jfro jfro commented Oct 16, 2025

Summary by CodeRabbit

  • New Features

    • Added a public exporter handle to request average metrics for specified keys.
    • Example program demonstrating querying the metrics DB and computing averages.
    • Ability to derive a time-bounded session from a signpost to scope queries.
  • Chores

    • Updated multiple runtime and dev dependencies.
    • CI enhanced with formatting checks and static analysis steps.
  • Bug Fixes

    • Derivative calculations now guard against non-positive time deltas.

@coderabbitai
Copy link

coderabbitai bot commented Oct 16, 2025

Walkthrough

Adds CI refinements and dependency bumps, introduces a SqliteExporterHandle and RequestSummaryFromSignpost flow to request averaged metrics, adds a MetricsDb.session_from_signpost API and a new internal query module, and adds an examples/summary.rs demonstration program.

Changes

Cohort / File(s) Summary
CI workflow & deps
\.github/workflows/rust.yml, Cargo.toml
Reworked GitHub Actions: added RUSTFLAGS, changed checkout to actions/checkout@v4, added steps for cargo fmt --check, cargo build --all --all-features, cargo test --verbose, and cargo clippy --all-targets --all-features. Bumped several dependencies and added anyhow as a dev-dependency.
Public API / exporter handle
src/lib.rs
Added public SqliteExporterHandle; changed SqliteExporter::install() to return Result<SqliteExporterHandle, SetRecorderError<_>>; added Event::RequestSummaryFromSignpost and a handle method to request averaged metrics; worker handles the request, computes averages, and responds via oneshot.
Metrics DB: session & query module
src/metrics_db.rs, src/metrics_db/query.rs
Added pub(crate) mod query and MetricsDb::session_from_signpost(&mut, &str) -> Result<Session> delegating to query module; added query utilities (metric_key_for_name, session_from_signpost, metrics_for_key, average_for_session, metrics_summary_for_signpost_and_keys); clamped derivative computation for non-positive dt and replaced CSV flush condition with is_multiple_of(200).
Example
examples/summary.rs
New example demonstrating opening MetricsDb, deriving a session from a signpost, computing averages for keys, and printing a formatted summary; uses tracing_subscriber and anyhow for setup and error handling.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Handle as SqliteExporterHandle
    participant Worker as ExporterWorker
    participant DB as MetricsDb

    Client->>Handle: request_average_metrics(signpost_key, keys)
    activate Handle
    Handle->>Worker: send RequestSummaryFromSignpost { signpost_key, keys, tx }
    deactivate Handle

    activate Worker
    Worker->>DB: session_from_signpost(signpost_key)
    activate DB
    DB-->>Worker: Session (start, end)
    deactivate DB

    loop for each key
        Worker->>DB: metrics_for_key(key, session)
        DB-->>Worker: Vec<Metric>
    end

    Worker->>Worker: compute averages & build HashMap
    Worker-->>Handle: send Result<HashMap> via oneshot tx
    deactivate Worker

    Handle-->>Client: return Result<HashMap<String,f64>>
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰
I hop through crates and CI light,
signposts point sessions through the night.
I average numbers, sip carrot tea,
send them back through a oneshot key.
Hooray — metrics neat as can be!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly highlights the core feature introduced—support for signpost metric sessions and a summary/average API—and directly corresponds to the main changes in the pull request without extraneous detail.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/signpost-metric-sessions

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bbbf2ad and f338e0a.

📒 Files selected for processing (5)
  • .github/workflows/rust.yml (2 hunks)
  • Cargo.toml (1 hunks)
  • examples/summary.rs (1 hunks)
  • src/lib.rs (10 hunks)
  • src/metrics_db.rs (7 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
examples/summary.rs (2)
src/lib.rs (5)
  • db (206-206)
  • new (156-170)
  • new (444-458)
  • average (277-283)
  • metrics (517-517)
src/metrics_db.rs (3)
  • new (35-41)
  • new (51-55)
  • metrics (78-81)
src/metrics_db.rs (1)
src/lib.rs (2)
  • setup_db (74-84)
  • db (206-206)
src/lib.rs (3)
src/metrics_db.rs (13)
  • metrics (78-81)
  • metric_key_for_key (133-140)
  • metric_keys (105-108)
  • query (70-70)
  • query (124-127)
  • query (128-128)
  • query (136-136)
  • query (183-183)
  • session_from_signpost (63-74)
  • end_query (72-72)
  • new (35-41)
  • new (51-55)
  • metrics_for_key (113-131)
src/models.rs (1)
  • query (93-93)
examples/summary.rs (1)
  • average (24-30)
🪛 actionlint (1.7.8)
.github/workflows/rust.yml

21-21: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build (windows-latest)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
.github/workflows/rust.yml (1)

26-27: Run tests with all features for parity.

cargo build and cargo clippy exercise every feature, but cargo test still runs with the default feature set. Adding --all-features (and optionally --all-targets) keeps coverage consistent and catches feature-gated test regressions earlier.

src/metrics_db/query.rs (1)

62-76: Use the existing session.duration field.

Line 73 recalculates the session duration as session.end_time - session.start_time, but Session already has a duration field (see Session::new in src/metrics_db.rs line 39) that computes this value. Reusing it avoids redundant computation and potential inconsistencies.

Apply this diff:

     let session = session_from_signpost(db, signpost)?;
     let mut results = HashMap::new();
     for key in keys {
         let value = average_for_session(db, &key, &session)?;
         results.insert(key, value);
     }
-    let duration_secs = session.end_time - session.start_time;
-    results.insert("session.duration".to_string(), duration_secs);
+    results.insert("session.duration".to_string(), session.duration.as_secs_f64());
     Ok(results)
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f338e0a and 8e46b7e.

📒 Files selected for processing (4)
  • .github/workflows/rust.yml (2 hunks)
  • src/lib.rs (11 hunks)
  • src/metrics_db.rs (7 hunks)
  • src/metrics_db/query.rs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/lib.rs (1)
src/metrics_db/query.rs (5)
  • query (11-11)
  • query (24-24)
  • query (41-44)
  • query (45-45)
  • metrics_summary_for_signpost_and_keys (62-76)
src/metrics_db.rs (2)
src/lib.rs (4)
  • setup_db (78-88)
  • new (160-174)
  • new (423-437)
  • db (210-210)
src/metrics_db/query.rs (6)
  • query (11-11)
  • query (24-24)
  • query (41-44)
  • query (45-45)
  • session_from_signpost (17-28)
  • metrics_for_key (30-48)
src/metrics_db/query.rs (2)
src/lib.rs (5)
  • db (210-210)
  • metrics (496-496)
  • new (160-174)
  • new (423-437)
  • metrics_summary_for_signpost_and_keys (252-258)
src/metrics_db.rs (6)
  • query (155-155)
  • session_from_signpost (65-67)
  • metrics (71-74)
  • new (35-41)
  • new (53-57)
  • metrics_for_key (106-112)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build (windows-latest)
🔇 Additional comments (4)
src/metrics_db.rs (2)

126-131: LGTM! Defensive clamping prevents negative derivatives.

The change correctly clamps the derivative to 0.0 when dt <= 0, preventing negative or undefined values from timestamp inversion or duplicate timestamps.


193-193: LGTM! Cleaner idiom for divisibility check.

Using is_multiple_of(200) is more readable and idiomatic than the previous modulo-based check.

src/lib.rs (2)

352-389: LGTM! Addresses the previous review concern.

The handler correctly flushes pending metrics (line 357) before querying the database, ensuring that the summary includes the most recent samples. Error handling is robust, with separate paths for flush errors and query errors.

Based on past review comments.


521-527: LGTM! Handle return enables communication after installation.

The updated signature allows callers to request averages after installing the exporter, which aligns well with the new SqliteExporterHandle API.

Copy link

@coderabbitai coderabbitai bot left a 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 (1)
src/metrics_db.rs (1)

126-131: Consider logging when time delta is non-positive.

The guard prevents division by zero and handles negative time deltas by returning 0.0, which is good defensive programming. However, these cases indicate data quality issues (identical or out-of-order timestamps) that could be difficult to debug without visibility. Consider adding a trace or warning log when dt <= 0 is encountered.

Apply this diff to add logging:

+use tracing::trace;
+
 pub fn deriv_metrics_for_key(
     &mut self,
     key_name: &str,
     session: Option<&Session>,
 ) -> Result<Vec<DerivMetric>> {
     let m = self.metrics_for_key(key_name, session)?;
     let new_values: Vec<_> = m
         .windows(2)
         .map(|v| {
             let dt = v[1].timestamp - v[0].timestamp;
             let new_value = if dt > 0.0 {
                 (v[1].value - v[0].value) / dt
             } else {
+                trace!(
+                    "Non-positive time delta (dt={}) for key '{}' between timestamps {} and {}, clamping derivative to 0.0",
+                    dt, key_name, v[0].timestamp, v[1].timestamp
+                );
                 0.0
             };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 8e46b7e and 48f9ae0.

📒 Files selected for processing (3)
  • src/lib.rs (11 hunks)
  • src/metrics_db.rs (7 hunks)
  • src/metrics_db/query.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/metrics_db/query.rs
🧰 Additional context used
🧬 Code graph analysis (2)
src/metrics_db.rs (2)
src/lib.rs (4)
  • setup_db (84-94)
  • new (166-180)
  • new (417-431)
  • db (216-216)
src/metrics_db/query.rs (6)
  • query (11-11)
  • query (24-24)
  • query (44-47)
  • query (48-48)
  • session_from_signpost (17-31)
  • metrics_for_key (33-51)
src/lib.rs (1)
src/metrics_db/query.rs (5)
  • query (11-11)
  • query (24-24)
  • query (44-47)
  • query (48-48)
  • metrics_summary_for_signpost_and_keys (68-82)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: build (windows-latest)
🔇 Additional comments (13)
src/metrics_db.rs (6)

2-11: LGTM!

The import additions (Path, Duration, error, trace) appropriately support the new query module and enhanced CSV import logging.


43-43: LGTM!

The new internal query module provides good separation of concerns by centralizing query and derivation logic.


64-67: LGTM!

The new session_from_signpost API is well-designed and properly delegates to the centralized query module. Error handling is appropriate.


111-111: LGTM!

Good refactoring to centralize query logic in the query module.


193-193: LGTM!

Using is_multiple_of is more idiomatic than the modulo check.


23-23: LGTM!

Documentation improvements and more idiomatic string interpolation in the derivative key format.

Also applies to: 34-34, 134-134

src/lib.rs (7)

59-67: LGTM!

The new error variants (ExporterUnavailable, ZeroLengthSession, NoMetricsForKey) appropriately support the new signpost-based session querying and handle edge cases.


114-119: LGTM!

The RequestSummaryFromSignpost event variant is well-designed for async query requests using a oneshot channel pattern.


121-145: LGTM!

The new SqliteExporterHandle and request_average_metrics API are well-designed:

  • Clean handle pattern for continued communication with the exporter
  • Proper error handling: channel failures correctly map to ExporterUnavailable (addressing the past review comment about error mapping)
  • Non-panicking design: uses map_err and ? instead of unwrap() (addressing past concern)

246-252: LGTM!

Appropriate delegation to the centralized query module for computing metrics summaries.


346-383: LGTM!

The RequestSummaryFromSignpost event handler is excellently implemented:

  • Correctly flushes pending metrics before querying (addressing the past review comment about ensuring up-to-date results)
  • Comprehensive error handling covering flush failures, query failures, and channel send failures
  • Appropriate logging for all error paths
  • Clean control flow

515-521: LGTM!

Good API improvement: returning the SqliteExporterHandle from install() enables callers to query metrics while the recorder is active.


77-77: LGTM!

Minor improvements including the new query module import, error construction refinement, and documentation enhancements.

Also applies to: 91-91, 412-412, 433-436

@jfro jfro merged commit d3d47a4 into main Oct 16, 2025
4 checks passed
@jfro jfro deleted the feature/signpost-metric-sessions branch October 16, 2025 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant