Skip to content

feat(swift-sdk): log tokio runtime metrics from rs-sdk-ffi and platform-wallet-ffi#3901

Merged
QuantumExplorer merged 1 commit into
v3.1-devfrom
feat/tokio_metrics
Jun 16, 2026
Merged

feat(swift-sdk): log tokio runtime metrics from rs-sdk-ffi and platform-wallet-ffi#3901
QuantumExplorer merged 1 commit into
v3.1-devfrom
feat/tokio_metrics

Conversation

@ZocoLini

@ZocoLini ZocoLini commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Adds an optional, dev-only observability layer that surfaces tokio runtime health for the two FFI runtimes behind the unified iOS SDK.

  • New tokio-metrics Cargo feature in rs-sdk-ffi and platform-wallet-ffi, forwarded through rs-unified-sdk-ffi. Off by default.
  • RuntimeMonitor sampler (1s interval) on each crate's shared runtime, logging busy_ratio, live_tasks, global/local_queue_depth, total_polls, mean_poll_us, steals, local/remote_schedules, overflow, etc.
  • SDK block_on instrumentation (BlockOnGuard): the SDK drives root futures on a dedicated large-stack OS thread that bypasses the runtime workers and is invisible to RuntimeMonitor. The guard times each FFI call (elapsed_us) and tracks concurrency (in_flight).
  • Dedicated per-crate log files: metrics route via tracing targets platform_wallet_ffi::metrics / rs_sdk_ffi::metrics into platform_wallet/metrics.log and dash_sdk/metrics.log, and are excluded from the corresponding run.log.
  • Enabled only for the dev iOS profile in build_ios.sh; release builds are unaffected.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Summary by CodeRabbit

  • New Features

    • Added optional tokio-metrics feature to enable periodic Tokio runtime monitoring (workers, tasks, busy ratio, queue depth, and polling stats) and per-block_on timing/in-flight tracking across SDK packages.
  • Bug Fixes

    • Improved file logging by writing SDK and wallet metrics to separate metrics.log files and failing file setup if any required log file can’t be opened.
  • Chores

    • Added workspace tokio-metrics dependency, forwarded the feature via the unified SDK, and enabled it automatically for iOS dev-ios builds.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds an optional tokio-metrics Cargo feature to rs-sdk-ffi, rs-platform-wallet-ffi, and rs-unified-sdk-ffi. When enabled, both runtime modules spawn background RuntimeMonitor samplers logging per-second telemetry, and BigStackRuntime::block_on tracks elapsed time and in-flight call count via RAII guards. The tracing subscriber extends to route metrics targets to dedicated metrics.log files with separate layer filters. The feature is auto-enabled for dev-iOS builds.

Changes

tokio-metrics feature rollout

Layer / File(s) Summary
Workspace dependency declaration
Cargo.toml
Declares tokio-metrics = "0.5" in workspace dependencies for shared use.
FFI Cargo feature declarations and unified forwarding
packages/rs-sdk-ffi/Cargo.toml, packages/rs-platform-wallet-ffi/Cargo.toml, packages/rs-unified-sdk-ffi/Cargo.toml
Declares tokio-metrics as optional dependency in rs-sdk-ffi (enables dep:tokio-metrics) and rs-platform-wallet-ffi (enables dep:tokio-metrics + tokio/time); forwards both features through unified tokio-metrics in rs-unified-sdk-ffi.
rs-sdk-ffi runtime metrics instrumentation
packages/rs-sdk-ffi/src/runtime.rs
Conditionally imports AtomicUsize and Ordering, calls spawn_sampler with unique atomic-counter-derived names in build_shared and new_isolated, wraps block_on with BlockOnGuard for per-call timing and in-flight tracking, and implements the metrics module with RAII BlockOnGuard drop-logging and spawn_sampler background task for periodic RuntimeMonitor telemetry.
rs-platform-wallet-ffi runtime metrics integration
packages/rs-platform-wallet-ffi/src/runtime.rs
Refactors runtime() to bind the Tokio runtime before returning; conditionally calls metrics::spawn_sampler(&rt) to spawn a background task that samples RuntimeMonitor intervals every 1 second and logs worker, task, busy, and polling statistics.
Tracing subscriber extension with metrics log files
packages/rs-platform-wallet-ffi/src/logging.rs
Opens dash_sdk/metrics.log and platform_wallet/metrics.log files; adds l_sdk_metrics and l_pw_metrics tracing layers routing ::metrics targets to dedicated files; disables ::metrics in existing l_sdk and l_pw layers; refactors layer assembly from fluent chaining to boxed Vec passed to .with(layers).
dev-iOS build script activation
packages/swift-sdk/build_ios.sh
Appends tokio-metrics to CARGO_FEATURES when PROFILE equals dev-ios.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Hop hop, the metrics flow,
Through layers watching fast and slow,
BlockOnGuard counts every call,
RuntimeMonitor logs them all!
In metrics.log the numbers gleam—
A rabbit's proudest telemetry dream! 📊

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding tokio runtime metrics logging to the Swift SDK's FFI runtimes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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 feat/tokio_metrics

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.

❤️ Share

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

@thepastaclaw

thepastaclaw commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

✅ Review complete (commit 6c3e59c)

@ZocoLini
ZocoLini force-pushed the feat/tokio_metrics branch 2 times, most recently from 9f0d110 to 3ff6011 Compare June 15, 2026 11:41

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review

Dev-only Tokio runtime observability behind an opt-in tokio-metrics feature; no consensus, storage, or FFI ABI surface is touched. Two real but minor issues remain: an unconditional import that becomes unused when the feature is off (CI uses --all-features so it does not fail CI, but pollutes default cargo check), and a sampler ordering quirk where the first emitted interval is near-zero. No blocking issues.

🟡 1 suggestion(s) | 💬 2 nitpick(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/rs-sdk-ffi/src/runtime.rs`:
- [SUGGESTION] packages/rs-sdk-ffi/src/runtime.rs:25: Gate AtomicUsize/Ordering import behind the tokio-metrics feature
  `use std::sync::atomic::{AtomicUsize, Ordering};` is unconditional, but both symbols are only referenced inside `#[cfg(feature = "tokio-metrics")]` blocks (lines 67/74 in `build_shared` and 91/98 in `new_isolated`); the inner `metrics` module re-imports them at line 181. Verified locally: `cargo check -p rs-sdk-ffi` (default features) emits `warning: unused imports: AtomicUsize and Ordering`. CI runs clippy with `--all-features` so it does not currently fail, but this still makes default `cargo build`/`cargo check` noisy for anyone working in this crate without enabling the feature. Codex's claim that this is blocking for the repo's `-D warnings` gate is incorrect — CI passes the all-features flag.

Comment thread packages/rs-sdk-ffi/src/runtime.rs
Comment thread packages/rs-sdk-ffi/src/runtime.rs
Comment thread packages/rs-platform-wallet-ffi/src/runtime.rs
@ZocoLini
ZocoLini force-pushed the feat/tokio_metrics branch from 3ff6011 to 771cbaa Compare June 15, 2026 11:58
@ZocoLini
ZocoLini force-pushed the feat/tokio_metrics branch from 771cbaa to 6c3e59c Compare June 15, 2026 12:08

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review

Three carried-forward nitpicks remain valid against 9f0d110: an unconditional AtomicUsize/Ordering import in rs-sdk-ffi that becomes an unused-import warning under default features, and the same next()-before-sleep ordering in both tokio-metrics samplers (rs-sdk-ffi and rs-platform-wallet-ffi) that shifts/skews emitted metrics by one interval. No new findings from the latest delta (logging.rs only) and no FFI ABI changes. All findings are non-blocking; consensus/proof paths are untouched.

💬 2 nitpick(s)

2 additional finding(s) omitted (not in diff).

1 carried-forward finding(s) already raised on this PR; not re-posting as new inline comments.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review

Cumulative review against head 3ff6011. All three prior findings are still valid: the unconditional AtomicUsize/Ordering imports in rs-sdk-ffi remain ungated (warn when tokio-metrics is off), and both RuntimeMonitor samplers (rs-sdk-ffi and rs-platform-wallet-ffi) still advance the interval iterator before awaiting the one-second sleep, producing a near-zero first record and one-period-stale subsequent records. No new in-scope blocking issues in the latest delta; CodeRabbit had zero inline findings.

💬 2 nitpick(s)

2 additional finding(s) omitted (not in diff).

1 carried-forward finding(s) already raised on this PR; not re-posting as new inline comments.

@github-actions

Copy link
Copy Markdown
Contributor

✅ DashSDKFFI.xcframework built for this PR.

SwiftPM (host the zip at a stable URL, then use):

.binaryTarget(
  name: "DashSDKFFI",
  url: "https://your.cdn.example/DashSDKFFI.xcframework.zip",
  checksum: "6bd6216957124b17dc0ebc93db840777668b940b8305908809433b26f3d76067"
)

Xcode manual integration:

  • Download 'DashSDKFFI.xcframework' artifact from the run link above.
  • Drag it into your app target (Frameworks, Libraries & Embedded Content) and set Embed & Sign.
  • If using the Swift wrapper package, point its binaryTarget to the xcframework location or add the package and place the xcframework at the expected path.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review

Cumulative review of HEAD 6c3e59c. All three prior findings from base 3ff6011 are FIXED: AtomicUsize/Ordering imports are properly gated behind #[cfg(feature = "tokio-metrics")] in rs-sdk-ffi/src/runtime.rs:25-26, and both rs-sdk-ffi and platform-wallet-ffi samplers correctly call tokio::time::sleep(...) before rt_intervals.next(). One new latest-delta suggestion from codex about restoring a BLOCK_ON_TOTAL counter to keep metric coverage aligned with the PR description; severity is suggestion-level since the feature is dev-only and the value can be approximated from event counts.

🟡 1 suggestion(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/rs-sdk-ffi/src/runtime.rs`:
- [SUGGESTION] packages/rs-sdk-ffi/src/runtime.rs:180-213: Emit total block_on count alongside in_flight
  The PR description states `BlockOnGuard` tracks both concurrency and cumulative FFI calls, but the current metrics module only maintains `BLOCK_ON_IN_FLIGHT` and emits `in_flight` on the `kind = "block_on"` event. Without a monotonic `total`, correlating sampled elapsed call durations against overall call volume in `dash_sdk/metrics.log` requires counting log events, which is fragile when only a subset of events are retained or the log is rotated. Add a `BLOCK_ON_TOTAL: AtomicU64` and include it on the emitted event so the per-call records are self-contained.

Comment thread packages/rs-sdk-ffi/src/runtime.rs
@QuantumExplorer
QuantumExplorer merged commit a82a865 into v3.1-dev Jun 16, 2026
22 of 23 checks passed
@QuantumExplorer
QuantumExplorer deleted the feat/tokio_metrics branch June 16, 2026 07:28
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.

3 participants