feat(power): real metered-network detection on macOS and Linux#95
Open
pmaxhogan wants to merge 1 commit into
Open
feat(power): real metered-network detection on macOS and Linux#95pmaxhogan wants to merge 1 commit into
pmaxhogan wants to merge 1 commit into
Conversation
Windows metered detection was already real (INetworkCostManager::GetCost); macOS and Linux returned a conservative unmetered stub, so skip_on_metered was inert there. Wire both: - Linux: read NetworkManager's aggregate Metered property over the system bus (zbus blocking API dispatched via spawn_blocking off the async executor, bounded by a 5s timeout so a wedged bus never stalls the poll). - macOS: a long-lived NWPathMonitor (Network.framework C API, block2 handler, libdispatch global queue) caches isExpensive || isConstrained - the documented metered proxy, since macOS has no literal metered bit. Refactor the classification into three pure classify_* functions plus MeteredStatus, all compiled and unit-tested on every OS so the decision logic is CI-covered on Windows, macOS, and Linux alike; only the thin OS-call adapters are compile-checked-only off their native OS. Every read collapses ambiguity to Unknown -> not metered (safe direction). Closes #32. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014fLmkjpFkiuky72eLBijL4
Contributor
Coverage
Gate: passed - no coverage regression (epsilon 0.1 pp). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Metered-network detection was real on Windows only (
INetworkCostManager::GetCost); macOS and Linux returned a conservative unmetered stub, soskip_on_meteredwas inert on those platforms (issue #32). This wires both.Meteredproperty (org.freedesktop.NetworkManager) over the system bus via zbus's blocking API, dispatched throughtokio::task::spawn_blocking(zbus's blocking API must not be driven from inside an async runtime) and bounded by a 5 s timeout so a wedged bus can never stall the AC/battery poll.NMMeteredYES/GUESS_YES -> metered, NO/GUESS_NO -> not metered, UNKNOWN or a failed read (no NetworkManager / no system bus) ->Unknown-> not metered.NWPathMonitor(Network.framework C API; its update handler is an Objective-C block viablock2, delivered on a libdispatch global queue) cachesnw_path_is_expensive(cellular / personal hotspot)|| nw_path_is_constrained(Low Data Mode) - the documented metered proxies - into anAtomicU8that the 30 s power poll reads cheaply.Design
The per-OS raw read is separated from the decision logic. Three pure
classify_*functions (classify_windows_cost,classify_nm_metered,classify_nw_path) plusMeteredStatus/on_meteredturn each OS's raw value into theon_metered_networkbool. They are#[cfg(any(test, target_os = ...))], so all three are compiled and unit-tested on every OS - the classification is CI-covered on Windows, macOS, and Linux alike; only the thin OS-call adapters (COM / D-Bus /NWPathMonitor) are compile-checked-only off their native OS.Every read collapses ambiguity to
MeteredStatus::Unknown, which maps tofalse(not metered) - the safe direction, since a wrong "not metered" only fails to skip a rare metered link whereas a wrong "metered" would stall ALL sync.No stored-format or public-API changes:
PowerStateshape and thePowerSourcetrait are unchanged; this is purely additive.Tested vs compile-only
Development was on Windows, so the non-Windows adapters are compile-verified via the 3-OS CI matrix, not locally:
classify_*functions,MeteredStatus::on_metered,from_u8,reachable_hint- the full decision logic.detect_metered()real COM read is total (windows_detect_metered_is_total); the existingRealPowerSourceconstruction tests exercise the read path.macos_monitor_start_and_read_is_totalstarts the realNWPathMonitorand reads its cache - the only runtime exercise of the Network.framework /block2/ libdispatch FFI (a wrong signature or bad link fails here).APIs were taken from documented sources (zbus proxy/blocking docs; Apple Network.framework; objc2/block2 encoding), not guessed.
Nothing deferred
macOS
isExpensive/isConstrainedis the documented, feasible proxy (macOS exposes no literal metered bit), so #32 is fully addressed rather than scope-reduced.Closes #32.
🤖 Generated with Claude Code