refactor: flatten test harness storage compat aliases (#3596)

* refactor: flatten test harness storage compat aliases

* refactor: flatten rustfs storage compat aliases (#3597)

* refactor: prune runtime storage compat surface (#3598)

* refactor: flatten runtime secondary storage compat (#3599)

* docs: add scheduler placement profiling baselines (#3600)

* feat: add observability topology capability contracts (#3601)
This commit is contained in:
安正超
2026-06-19 08:30:47 +08:00
committed by GitHub
parent b1c6578df1
commit ada6f7587e
87 changed files with 1551 additions and 990 deletions
+3
View File
@@ -92,14 +92,17 @@ Required `rustfs-storage-api` public re-exports:
- `pub use admin::{DiskSetSelector, StorageAdminApi};`
- `pub use bucket::{BucketInfo, BucketOperations, BucketOptions, DeleteBucketOptions, MakeBucketOptions, SRBucketDeleteOp};`
- `pub use capability::{CapabilitySnapshotError, CapabilityState, CapabilityStatus};`
- `pub use error::{StorageErrorCode, StorageResult};`
- `pub use multipart::{CompletePart, ListMultipartsInfo, ListPartsInfo, MultipartInfo, MultipartUploadResult, PartInfo};`
- `pub use observability::{MemorySamplingState, ObservabilitySnapshot, ObservabilitySnapshotProvider, PlatformSupport, UserspaceProfilingCapability};`
- `pub use object::{HTTPPreconditions, HTTPRangeError, HTTPRangeSpec, ObjectLockRetentionOptions};`
- `pub use object::{ExpirationOptions, TransitionedObject};`
- `pub use object::{HealOperations, MultipartOperations, NamespaceLocking, ObjectIO, ObjectOperations};`
- `pub use object::{ListObjectVersionsInfo, ListObjectsInfo, ListObjectsV2Info, ListOperations, ObjectInfoOrErr};`
- `pub use object::{ObjectPreconditionError, ObjectPreconditionPart, ObjectPreconditionState};`
- `pub use object::{VersionMarker, WalkOptions, WalkVersionsSortOrder};`
- `pub use topology::{DiskCapabilities, TopologyCapabilities, TopologyDisk, TopologyLabels, TopologyPool, TopologySet, TopologySnapshot, TopologySnapshotProvider};`
ECStore must keep compile-time coverage for `StorageAdminApi`, `HealOperations`,
and the separate `NamespaceLocking` operation group.
+224 -15
View File
@@ -5,17 +5,19 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
## Current Context
- Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660)
- Branch: `overtrue/arch-storage-api-lifecycle-contracts`
- Baseline: stacked on `rustfs/rustfs#3594` head
(`6fc05b84e2cd22a0482adfbc042184b03f8fdfa6`).
- PR type for this branch: `pure-move`
- Runtime behavior changes: no migration behavior change expected.
- Rust code changes: move lifecycle helper DTO contracts for expiration and
transitioned object metadata into rustfs-storage-api, switch ECStore internal
consumers to direct storage-api imports, and keep ECStore old-path re-exports.
- CI/script changes: add migration guards rejecting reintroduced ECStore
lifecycle helper DTO definitions and old internal consumer imports.
- Docs changes: record the lifecycle helper pure-move slice.
- Branch: `overtrue/arch-observability-topology-contracts`
- Baseline: stacked on `origin/overtrue/arch-test-harness-compat-aliases`
after `rustfs/rustfs#3600`
(`ae6a5befcf60f2f2ebce9799ba93649032234273`).
- PR type for this branch: `contract`
- Runtime behavior changes: none.
- Rust code changes: add observability and topology capability DTO/trait
contracts to `rustfs-storage-api`.
- CI/script changes: extend migration re-export guard coverage for the new
contract exports.
- Docs changes: add
[`runtime-capability-contracts.md`](runtime-capability-contracts.md) and
record the combined PR-08/API-013 plus PR-09/API-014 contract slice.
## Phase 0 Tasks
@@ -63,6 +65,60 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
[`ecstore-config-consumer-inventory.md`](ecstore-config-consumer-inventory.md)
records the current model definitions, global accessors, persistence helpers,
consumer groups, migration risks, and do-not-change contract.
- [x] `G-011` Inventory scheduler baseline.
- Acceptance:
[`scheduler-baseline.md`](scheduler-baseline.md) records current owners for
request admission, reusable scheduler/backpressure facades, workers, scanner
budget, heal admission, and the Tokio runtime builder.
- Must preserve: no Rust source changes, no scheduler/controller contract
changes, and no runtime behavior changes.
- [x] `G-012` Inventory placement and repair invariants.
- Acceptance:
[`placement-repair-invariants.md`](placement-repair-invariants.md) records
object-to-set hashing, pool/set/disk assignment boundaries, set-aware
readiness and lock quorum, scanner budget, and heal admission preservation
gates.
- Must preserve: no placement, repair, scanner, heal, readiness, lock, or
storage metadata behavior changes.
- [x] `G-013` Inventory profiling and NUMA capabilities.
- Acceptance:
[`profiling-numa-capability-inventory.md`](profiling-numa-capability-inventory.md)
records current CPU/memory profiling, cgroup memory sampling, allocator
backend, eBPF, and NUMA capability support plus no-op fallback invariants.
- Must preserve: no startup, profiling, allocator, runtime, or platform-gate
behavior changes.
## Issue #660 Capability Contract Tasks
- [x] `PR-08/API-013` Add observability snapshot contract.
- Completed slice: add `CapabilityState`, `CapabilityStatus`,
`CapabilitySnapshotError`, `ObservabilitySnapshot`,
`UserspaceProfilingCapability`, `MemorySamplingState`,
`PlatformSupport`, and `ObservabilitySnapshotProvider` to
`rustfs-storage-api`.
- Acceptance: runtime telemetry, userspace profiling, memory sampling, and
platform support states are representable without runtime, ECStore, admin,
profiling, exporter, sidecar, eBPF, or OTEL implementation dependencies.
- Must preserve: no profiling, startup, admin route, exporter, sidecar, eBPF,
OTEL, or runtime behavior changes.
- Verification: storage-api contract tests for unknown, unsupported,
disabled, and supported capability states; focused storage-api check;
migration guard; formatting; diff hygiene; and three-expert review.
- [x] `PR-09/API-014` Add topology capability contract.
- Completed slice: add `TopologySnapshot`, `TopologyCapabilities`,
`TopologyPool`, `TopologySet`, `TopologyDisk`, `TopologyLabels`,
`DiskCapabilities`, and `TopologySnapshotProvider` to
`rustfs-storage-api`.
- Acceptance: pool, set, and disk identity fields plus optional zone, rack,
node, media, NUMA, and additional labels are representable without
`rustfs-ecstore`.
- Must preserve: no ECStore endpoint/set implementation, placement,
membership, NUMA pinning, or runtime behavior changes.
- Verification: storage-api contract tests for missing and additional labels
plus supported, unsupported, unknown, and disabled capability states;
focused storage-api check; migration guard; formatting; diff hygiene; and
three-expert review.
- [x] `TEST-PRTYPE-001` Check PR type enum consistency.
- Acceptance: `./scripts/check_architecture_migration_rules.sh` parses the
allowed PR types from [`crate-boundaries.md`](crate-boundaries.md) and fails
@@ -1296,6 +1352,87 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
migration and layer guards, formatting check, diff hygiene, risk scan, full
pre-commit, and required three-expert review passed before push.
- [x] `API-051` Flatten test harness storage compatibility aliases.
- Current branch: `overtrue/arch-test-harness-compat-aliases`.
- Current slice: flatten e2e, heal, scanner, and fuzz storage compatibility
harnesses from nested `storage_compat::ecstore` modules into direct
crate-local aliases, constants, and function imports.
- Acceptance: no e2e, heal-test, scanner-test, or fuzz-target harness file
may expose or consume nested `storage_compat::ecstore` paths, and migration
rules reject reintroducing nested test/fuzz ECStore compatibility modules.
- Must preserve: e2e bucket target/RPC/disk helper imports, heal ECStore disk
and endpoint setup, scanner lifecycle/tier/disk/storage setup, fuzz bucket
validation behavior, and fuzz path-containment validation behavior.
- Risk defense: this is test-harness and fuzz-harness import cleanup only; no
production runtime behavior, ECStore ownership, storage metadata format, or
scanner/heal lifecycle logic is changed.
- Verification: focused e2e/heal/scanner test compile, harness tests,
migration and layer guards, formatting check, diff hygiene, risk scan, full
pre-commit, and required three-expert review passed before push.
- [x] `API-052` Flatten RustFS runtime storage compatibility aliases.
- Current branch: `overtrue/arch-rustfs-storage-compat-aliases`.
- Current slice: flatten RustFS root, app, admin, and storage runtime
compatibility facades from nested `storage_compat::ecstore` modules into
direct crate-local aliases, constants, and function imports.
- Acceptance: no RustFS runtime source file may expose or consume nested
`storage_compat::ecstore` paths, and migration rules reject reintroducing
nested RustFS runtime ECStore compatibility modules.
- Must preserve: startup/config/bootstrap behavior, server readiness checks,
admin replication/rebalance/tier/config handlers, app object/bucket/
multipart usecases, storage RPC/SSE/access paths, table catalog storage
access, and existing local compatibility ownership.
- Risk defense: this is RustFS runtime import cleanup only; no production
runtime behavior, ECStore ownership, storage metadata format, object I/O,
admin authorization, or readiness semantics are changed.
- Verification: focused RustFS compile, migration and layer guards,
formatting check, diff hygiene, risk scan, full pre-commit, and required
three-expert review passed before push.
- [x] `API-053` Flatten RustFS runtime scalar storage compatibility aliases.
- Current branch: `overtrue/arch-runtime-compat-surface-prune`.
- Current slice: flatten RustFS root, app, admin, and storage runtime scalar
compatibility facades such as store, error, global, endpoints, RPC,
metrics, notification, set-disk, and data-usage paths into direct
crate-local aliases and functions.
- Acceptance: RustFS runtime source no longer consumes those scalar
compatibility surfaces through secondary modules, while higher-coupling
bucket/config/rio compatibility modules remain unchanged; migration rules
reject restoring the flattened scalar paths.
- Must preserve: startup config/bootstrap behavior, server readiness checks,
admin replication/rebalance/tier/config handlers, app object/bucket/
multipart usecases, storage RPC/SSE/access paths, table catalog storage
access, and existing ECStore concrete type ownership.
- Risk defense: this is import ownership and facade-shape cleanup only; no
production runtime behavior, ECStore ownership, storage metadata format,
object I/O, admin authorization, or readiness semantics are changed.
- Verification: focused RustFS compile, migration and layer guards,
formatting check, diff hygiene, risk scan, full pre-commit, and required
three-expert review passed before push.
- [x] `API-054` Flatten RustFS runtime secondary storage compatibility aliases.
- Current branch: `overtrue/arch-runtime-secondary-compat-flatten`.
- Current slice: flatten RustFS root, app, admin, and storage runtime
secondary compatibility modules such as bucket, config, rio, client, tier,
compress, disk, and rebalance into direct crate-local aliases, modules, and
functions.
- Acceptance: RustFS runtime source no longer consumes those compatibility
surfaces through broad secondary modules, the runtime compatibility files no
longer define those wrapper modules, and migration rules reject restoring
the flattened secondary paths.
- Must preserve: startup config/bootstrap behavior, server module-switch
config reads, embedded startup storage initialization, admin bucket/meta/
tier/rebalance/config handlers, app object/bucket/multipart usecases,
storage RPC/SSE/access paths, table catalog storage access, and ECStore
concrete type ownership.
- Risk defense: this is import ownership and facade-shape cleanup only; no
production runtime behavior, ECStore ownership, storage metadata format,
object I/O, admin authorization, tier behavior, or readiness semantics are
changed.
- Verification: focused RustFS compile, migration and layer guards,
formatting check, diff hygiene, risk scan, and required three-expert review
passed before push.
## Phase 8 Background Controller Tasks
- [x] `BGC-001` Inventory background services.
@@ -1564,7 +1701,10 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
## Next PRs
1. `pure-move`/`consumer-migration`: continue larger cleanup slices with the
1. `contract`/`consumer-migration`: wire read-only observability and topology
snapshots to implementation owners without changing runtime, profiling,
placement, or admin route behavior.
2. `pure-move`/`consumer-migration`: continue larger cleanup slices with the
loss-prevention guards active for remaining ECStore compatibility contracts
now that broad compatibility passthroughs are fully closed.
@@ -1572,14 +1712,65 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
| Expert | Status | Notes |
|---|---|---|
| Quality/architecture | passed | S-015 removes obsolete KMS admin policy action variants after the handler fallback cleanup; API-042/API-043/API-044/API-045/API-046/API-047/API-048/API-049/API-050 narrow notify, S3 Select, OBS, IAM, Swift, heal, scanner, RustFS runtime, test, fuzz, and lifecycle helper compatibility contracts without moving ECStore storage metadata ownership. |
| Migration preservation | passed | KMS endpoint URLs, query aliases, request bodies, response contracts, and dedicated `kms:*` authorization behavior are preserved; event builder call sites, ECStore event bridge conversion, restore event data, version IDs, metadata filtering, config read/save semantics, S3 Select store/error/buffer semantics, OBS metrics state reads, IAM config/notification/error semantics, Swift bucket metadata access, heal disk/resume/task behavior, scanner lifecycle/replication/data-usage behavior, RustFS startup/admin/app/storage runtime access, e2e/test/fuzz import behavior, lifecycle expiration/transition helper DTO field contracts, unchanged no-op handling, and remove-event behavior are preserved. |
| Testing/verification | passed | Focused compiles/tests, guards, formatting, diff hygiene, risk scan, and full `make pre-commit` passed for the current slice. |
| Quality/architecture | passed | S-015 removes obsolete KMS admin policy action variants after the handler fallback cleanup; API-042/API-043/API-044/API-045/API-046/API-047/API-048/API-049/API-050/API-051/API-052/API-053/API-054 narrow notify, S3 Select, OBS, IAM, Swift, heal, scanner, RustFS runtime, test, fuzz, lifecycle helper, harness, and RustFS runtime compatibility contracts without moving ECStore storage metadata ownership; G-011/G-012/G-013 add docs-only baselines for scheduler, placement/repair, and profiling/NUMA work; Issue #660 PR-08/PR-09 add read-only observability and topology contracts in rustfs-storage-api only. |
| Migration preservation | passed | KMS endpoint URLs, query aliases, request bodies, response contracts, and dedicated `kms:*` authorization behavior are preserved; event builder call sites, ECStore event bridge conversion, restore event data, version IDs, metadata filtering, config read/save semantics, S3 Select store/error/buffer semantics, OBS metrics state reads, IAM config/notification/error semantics, Swift bucket metadata access, heal disk/resume/task behavior, scanner lifecycle/replication/data-usage behavior, RustFS startup/admin/app/storage runtime access, e2e/test/fuzz import behavior, lifecycle expiration/transition helper DTO field contracts, flattened harness and RustFS runtime scalar/secondary alias behavior, unchanged no-op handling, remove-event behavior, scheduler/readiness/placement/profiling runtime behavior, platform gates, missing/unknown capability states, and placement/topology labels are preserved. |
| Testing/verification | passed | Focused compiles/tests, fuzz target compile, guards, formatting, diff hygiene, risk scan, and full `make pre-commit` passed for prior code slices; current Issue #660 PR-08/PR-09 contract slice uses storage-api tests/checks, migration guard, formatting, diff hygiene, and three-expert review. |
## Verification Notes
Passed before push:
- Issue #660 PR-08/PR-09 current slice:
- `cargo test -p rustfs-storage-api`: passed.
- `cargo check -p rustfs-storage-api`: passed.
- `./scripts/check_architecture_migration_rules.sh`: passed.
- `./scripts/check_layer_dependencies.sh`: passed.
- `cargo fmt --all --check`: passed.
- `git diff --check`: passed.
- `make pre-commit`: passed.
- Three-expert review: passed.
- G-011/G-012/G-013 current slice:
- `./scripts/check_architecture_migration_rules.sh`: passed.
- `git diff --check`: passed.
- Three-expert review: passed.
- Full `make pre-commit`: not run because this slice is documentation-only.
- API-054 current slice:
- `cargo check -p rustfs --lib`: passed.
- `cargo check --tests -p rustfs`: passed.
- `./scripts/check_architecture_migration_rules.sh`: passed.
- `./scripts/check_layer_dependencies.sh`: passed.
- `cargo fmt --all --check`: passed.
- `git diff --check`: passed.
- Rust risk scan: passed; only existing import and path rewrites were
reviewed, with no new unwrap/expect, panic/todo/unsafe, risky casts,
ad-hoc error construction, or sensitive-token handling semantics.
- API-053 current slice:
- `cargo check -p rustfs --lib`: passed.
- `cargo check --tests -p rustfs`: passed.
- `./scripts/check_architecture_migration_rules.sh`: passed.
- `./scripts/check_layer_dependencies.sh`: passed.
- `cargo fmt --all --check`: passed.
- `git diff --check`: passed.
- Rust risk scan: passed; only existing import and path rewrites were
reviewed, with no new unwrap/expect, panic/todo/unsafe, risky casts,
ad-hoc error construction, or sensitive-token handling semantics.
- `make pre-commit`: passed.
- API-052 current slice:
- `cargo check -p rustfs --lib`: passed.
- `cargo check --tests -p rustfs`: passed.
- `./scripts/check_architecture_migration_rules.sh`: passed.
- `./scripts/check_layer_dependencies.sh`: passed.
- `cargo fmt --all --check`: passed.
- `git diff --check`: passed.
- Rust risk scan: passed; only existing-semantic path replacement hits were
reviewed, with no new unwrap/expect, panic/todo/unsafe, risky casts,
ad-hoc error construction, or sensitive-token handling semantics.
- `make pre-commit`: passed, including 6250 nextest tests and doctests.
- API-050 current slice:
- `cargo test -p rustfs-storage-api lifecycle_helper_defaults_preserve_existing_contracts --no-fail-fast`:
passed.
@@ -1598,6 +1789,24 @@ Passed before push:
lines.
- `make pre-commit`: passed.
- API-051 current slice:
- `cargo check --tests -p e2e_test -p rustfs-heal -p rustfs-scanner`:
passed.
- `cargo check --manifest-path fuzz/Cargo.toml --all-targets`: passed.
- `cargo test -p rustfs-heal --test endpoint_index_test test_endpoint_index_settings --no-fail-fast`:
passed.
- `cargo test -p rustfs-scanner --test lifecycle_integration_test --no-run`:
passed.
- `cargo test -p e2e_test --no-run`: passed.
- `./scripts/check_architecture_migration_rules.sh`: passed.
- `./scripts/check_layer_dependencies.sh`: passed.
- `cargo fmt --all --check`: passed.
- `git diff --check`: passed.
- Rust risk scan: passed; only existing test `unwrap` calls were touched by
import path rewrites, with no new unwrap/expect, panic/todo/unsafe, risky
casts, ad-hoc error construction, or sensitive-token handling semantics.
- `make pre-commit`: passed.
- S-015 current slice:
- `cargo test -p rustfs-policy test_legacy_kms_admin_actions_are_rejected --no-fail-fast`:
passed.
@@ -0,0 +1,97 @@
# Placement And Repair Invariants
This inventory covers `G-012` for `rustfs/backlog#666`. It records the current
object placement, readiness, lock quorum, scanner, and repair boundaries that
later scheduler or topology work must preserve.
## Object To Set Hash Rule
Objects reach a set through `Sets::get_disks_by_key`, which calls
`get_hashed_set_index` on the object key:
- `DistributionAlgoVersion::V1` uses `crc_hash(input, set_count)`.
- `DistributionAlgoVersion::V2` and `V3` use
`sip_hash(input, set_count, format_id_bytes)`.
- The format ID is part of the V2/V3 distribution seed, so changing the seed,
object key, set count, or algorithm changes placement.
Preservation rule: every object read, write, list, heal, repair, and
decommission path that resolves a set for an existing object must preserve the
same object key and format distribution algorithm.
## Pool, Set, And Disk Assignment Boundary
Pool selection is separate from set hashing:
- Existing objects are discovered across pools and resolved to the best current
pool candidate before reads or updates continue.
- New object writes select an available pool from current per-pool free-space
inputs after suspended or rebalancing pools are skipped.
- Set selection inside a pool still uses the object-to-set hash rule above.
- Disk index assignment comes from endpoint and format metadata, not from a
scheduler decision.
Boundary rule: schedulers may influence admission, worker concurrency, or
buffer sizing, but they must not rewrite pool, set, or disk indexes.
## Readiness And Lock Quorum Boundary
Runtime readiness currently checks storage and lock health independently:
- Storage readiness requires every observed set to meet write quorum based on
the set drive count and storage class data/parity shape.
- Lock readiness aggregates per-set lock-client host quorum and fails fast if
any set loses quorum.
- Object and bucket mutations acquire namespace locks through the existing
storage lock wrappers before changing object or bucket state.
Boundary rule: readiness and lock quorum must stay set-aware. A global healthy
disk count or global connected-host count is not sufficient when any individual
set is below quorum.
## Scanner Budget Preservation
Scanner cycles are bounded by `ScannerCycleBudget`:
- Runtime budget cancels the child token after the configured duration.
- Object budget cancels after the configured object count.
- Directory budget rejects additional directories and cancels with the
directories reason.
- Partial-cycle metrics and checkpoints use the budget reason.
Preservation rule: later scheduler work can change how scan cycles are admitted
only if it preserves the budget reason, checkpoint reason, and child-token
cancellation behavior.
## Heal Admission Preservation
Scanner and background repair work enter the heal manager through explicit
admission:
- Scanner object heal requests are low priority and may be accepted, merged,
rejected as full, or dropped.
- Required/high-priority heal candidates escalate on non-admission instead of
silently disappearing.
- Heal queue admission deduplicates queued and active work unless the request
explicitly forces admission.
- Full queues can drop low-priority work or displace lower-priority work for a
higher-priority request according to current manager rules.
Preservation rule: repair scheduling changes must keep admission outcomes
observable and must not convert rejected or dropped repair work into silent
success.
## Behavior Change Gates
Any later placement or repair PR must use the following gates:
- Placement gate: prove object-to-set hashing is unchanged for existing object
keys and format algorithms.
- Pool gate: prove pool selection does not choose suspended or rebalancing
pools unless the existing path already allows it.
- Quorum gate: prove storage readiness and lock readiness remain per-set.
- Scanner gate: prove scan budget reason and checkpoint mapping remain stable.
- Heal gate: prove low-priority scanner heal, forced heal, duplicate merge, and
queue-full outcomes remain distinct.
- Rollback gate: if a new scheduler sidecar is disabled, placement and repair
must fall back to the current direct ECStore/scanner/heal behavior.
@@ -0,0 +1,81 @@
# Profiling And NUMA Capability Inventory
This inventory covers `G-013` for `rustfs/backlog#667`. It records the current
profiling, memory sampling, allocator, and NUMA baseline before optional runtime
sidecars are designed.
## Platform Support Matrix
| Capability | Current support | Current owner | Baseline recommendation |
|---|---|---|---|
| CPU pprof dump | Linux and macOS builds use `pprof`; other targets return an unsupported-platform error. | `rustfs/src/profiling.rs` | Keep CPU profiling opt-in through existing env flags and cancellation token. |
| Continuous CPU profiling | Linux and macOS builds can hold a continuous `ProfilerGuard` when enabled. | `rustfs/src/profiling.rs` | Preserve single-guard ownership and avoid starting multiple continuous guards. |
| Periodic CPU profiling | Linux and macOS builds can spawn a periodic sampling loop. | `rustfs/src/profiling.rs` | Keep the loop cancellation-driven and non-fatal. |
| Jemalloc memory pprof | Only `linux` + `gnu` + `x86_64` exposes jemalloc pprof dumping. Other supported builds return an unsupported-target error. | `rustfs/src/profiling.rs` | Treat memory pprof as optional and target-gated. |
| Periodic memory pprof | Only runs where jemalloc profiling control is available and active. | `rustfs/src/profiling.rs` | Keep inactive jemalloc as a skipped dump, not a startup failure. |
| Process/system memory sampling | Uses `rustfs_io_metrics::snapshot_process_resource_and_system` plus `sysinfo` total memory. | `rustfs/src/memory_observability.rs` | Keep sampling portable and metric-gated. |
| cgroup memory sampling | Reads Linux cgroup v2 or v1 memory files when present. Missing files produce no cgroup split. | `rustfs/src/memory_observability.rs` | Keep cgroup data opportunistic and absent-safe. |
| Allocator reclaim | Uses jemalloc backend on `linux` + `gnu` + `x86_64`; otherwise mimalloc variants. | `rustfs/src/allocator_reclaim.rs` | Keep backend detection read-only and preserve effective-force behavior. |
| eBPF | No runtime eBPF sidecar is currently wired into startup. | N/A | Treat eBPF as future optional Linux-only inventory, never as a required baseline. |
| NUMA | No NUMA placement or topology controller is currently wired into startup. | N/A | Treat NUMA as future optional capability with no-op fallback. |
## Cross-Platform Baseline
The current safe baseline is:
- Profiling is opt-in through env flags and must not make startup fatal.
- Unsupported profiling targets return structured unsupported errors or skip
startup tasks.
- Memory observability records process/system metrics and adds cgroup split
only when cgroup files exist.
- Allocator reclaim observes active HTTP, delete-tail, scanner, heal, erasure,
and GET-buffer activity before reclaiming.
- Runtime thread sizing remains owned by the Tokio runtime builder and sysinfo
core detection, not NUMA topology.
## Optional Sidecar Invariants
Future sidecars for profiling, eBPF, or NUMA must preserve these invariants:
- Sidecars must be disabled by default or target-gated until explicitly enabled.
- Unsupported targets must degrade to no-op status, not panic or fail startup.
- Sidecars must use the runtime cancellation token or an equivalent explicit
shutdown handle.
- Sidecars must not mutate Tokio worker counts after runtime creation.
- Profiling output directory fallback must stay local to profiling and must not
affect object storage paths.
- NUMA fallback must preserve current runtime thread defaults, storage set
placement, and request admission behavior.
## First Implementation Candidates
`API-013`:
- Define a read-only capability contract for profiling, cgroup memory, eBPF,
allocator backend, and NUMA availability.
- Keep the contract in a low-dependency crate and report unsupported states
explicitly.
`R-016`:
- Wire storage runtime startup to consume capability snapshots read-only.
- Do not start sidecars or mutate runtime worker ownership in the same PR.
`X-012`:
- Add an optional profiling/eBPF extension point that can observe capability
status.
- Keep unsupported targets and disabled sidecars as no-op.
`X-013`:
- Add extension tests for disabled, unsupported, and enabled capability
snapshots.
- Verify no startup fatal boundary is added for optional profiling sidecars.
`R-017`:
- If a runtime service sidecar is added later, start it from the startup service
boundary with explicit shutdown ownership.
- Preserve current service order, KMS/audit/notification fatal boundaries, and
scanner/heal startup semantics.
@@ -0,0 +1,44 @@
# Runtime Capability Contracts
This document records the `rustfs/backlog#660` PR-08 and PR-09 contract slice.
It adds read-only observability and topology snapshot shapes to
`rustfs-storage-api` without coupling the contract crate to runtime, ECStore,
admin routes, profiling, or observability implementation crates.
## Observability Snapshot Contract
`ObservabilitySnapshot` records:
- Runtime telemetry capability state.
- Userspace CPU and memory profiling capability state.
- Process, system, and cgroup memory sampling state.
- Platform support for target triple, OS, architecture, allocator, eBPF, and
NUMA capability.
Unsupported, disabled, and unknown states are represented by `CapabilityState`
instead of failing snapshot construction. The contract is intentionally read
only and does not replace existing profiling routes, telemetry APIs, exporter
pipelines, or startup behavior.
## Topology Snapshot Contract
`TopologySnapshot` records:
- Pool, set, and disk identity indexes plus optional stable IDs.
- Optional zone, rack, node, media, NUMA, and additional labels.
- Topology-wide profiling, NUMA, failure-domain label, and media-label
capability states.
- Per-disk media, failure-domain, NUMA, and profiling capability states.
Missing labels are represented as absent `Option` values. Extra topology labels
belong in the `additional` label map, so future inventory labels do not require
ECStore type leakage.
## Boundary Rules
- No `rustfs-ecstore`, `rustfs-obs`, Axum, KMS, admin route, OTEL, eBPF, or
profiling implementation dependency is added to `rustfs-storage-api`.
- No placement, membership, NUMA pinning, profiling, startup, admin route, or
exporter behavior changes are part of this contract slice.
- Providers must map implementation failures into `CapabilitySnapshotError`
before crossing the contract boundary.
+78
View File
@@ -0,0 +1,78 @@
# Scheduler Baseline Inventory
This inventory covers `G-011` for `rustfs/backlog#675`. It is a docs-only
snapshot of the current scheduling, backpressure, worker, scanner, heal, and
runtime-builder ownership. It does not define new behavior.
## Current Owners
| Surface | Current owner | Current responsibility | Migration boundary |
|---|---|---|---|
| `ConcurrencyManager` | `rustfs/src/storage/concurrency/manager.rs` | Owns the RustFS S3 read-path disk-read semaphore, I/O metrics, priority queue, storage media detection, access-pattern detection, and buffer strategy. | Keep request admission and I/O metrics behavior stable until a controller can consume the same state explicitly. |
| `SchedulerManager` | `crates/concurrency/src/scheduler.rs` | Provides a reusable facade over `rustfs-io-core::IoScheduler` and derives buffer/priority decisions from `SchedulerPolicy`. | Treat it as reusable library surface; do not assume the RustFS S3 read path has already moved to this facade. |
| `BackpressureManager` | `crates/concurrency/src/backpressure.rs` | Provides a reusable duplex-pipe backpressure facade over `rustfs-io-core::BackpressureMonitor`. | Keep pipe sizing and watermark policy separate from object-read disk semaphore admission. |
| RustFS backpressure monitor | `rustfs/src/storage/backpressure.rs` | Tracks object-pipe watermark state used by RustFS storage backpressure tests and helpers. | Preserve current state labels and watermark semantics when consolidating with reusable facades. |
| `Workers` | `crates/concurrency/src/workers.rs` | Provides cooperative worker-slot admission with `take`, `give`, and `wait`; current background workflows use it for bounded set workers. | Preserve blocking/wakeup semantics and over-release clamping. |
| Scanner cycle budget | `crates/scanner/src/scanner_budget.rs` | Cancels a child token when runtime, object-count, or directory-count budget is reached. | Preserve partial-cycle reason mapping and checkpoint accounting. |
| Heal admission | `crates/heal/src/heal/manager.rs`, `crates/heal/src/heal/channel.rs`, `rustfs_common::heal_channel` | Owns priority queue admission, duplicate merge/drop/full results, active-task tracking, retry admission, and channel responses. | Preserve low-priority scanner behavior and high-priority escalation gates. |
| Tokio runtime builder | `rustfs/src/server/runtime.rs` | Builds the multi-thread runtime from env/defaults, sets thread counts, stack, queue/event intervals, I/O event cap, thread name, and optional dial9 tracing. | Keep runtime defaults and env names stable when later startup phases move ownership. |
## Current Flow
```mermaid
flowchart TD
http["HTTP/S3 request"] --> app["app object usecase"]
app --> guard["ConcurrencyManager::track_request"]
app --> permit["disk-read semaphore permit"]
permit --> strategy["I/O queue status and buffer strategy"]
strategy --> ecstore["ECStore object/read path"]
ecstore --> setdisks["hashed set disks"]
scanner["scanner cycle"] --> budget["ScannerCycleBudget"]
budget --> folder["folder/object scan"]
folder --> healreq["heal channel request"]
healreq --> admission["HealManager admission queue"]
admission --> healworker["heal workers and retries"]
startup["startup entrypoint"] --> runtime["Tokio runtime builder"]
runtime --> services["background services"]
```
## Missing State For Later Work
`R-015` storage foundation:
- Needs a stable inventory of endpoint publication, local disk prewarm, lock
client setup, and per-set readiness state before any scheduler/controller
consumes storage topology.
- Must not infer set availability only from request-path I/O metrics.
`E-011` extension/runtime consumers:
- Need explicit ownership for runtime admission snapshots before extensions can
observe scheduler or backpressure state.
- Must not receive mutable handles to `ConcurrencyManager`, heal queues, or
scanner budget tokens.
`C-011` controller work:
- Needs desired/current/status snapshots for request admission, scanner budget,
and heal queue pressure before any controller can reconcile them.
- Must keep worker mutation explicit. Read-only status should report `None` or
no-op mutation until a reviewed worker lifecycle PR exists.
## Preservation Invariants
- Request reads must keep the same disk-read semaphore admission and active GET
accounting.
- I/O queue status and congestion metrics must remain derived from the same
permit counts.
- Scanner budget cancellation must keep its reason as runtime, objects, or
directories.
- Scanner inline-heal compatibility must continue to use asynchronous heal
admission.
- Heal duplicate admission must prefer merge semantics before full-queue
rejection.
- High-priority heal admission must still be able to displace lower-priority
queued work where the current manager allows it.
- Tokio runtime env names and fallback defaults must remain unchanged.