mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-09 06:39:25 +00:00
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:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user