mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-18 18:46:17 +00:00
refactor(storage): narrow resync metadata bounds (#3345)
This commit is contained in:
@@ -27,7 +27,7 @@ use crate::bucket::replication::replication_state::ReplicationStats;
|
|||||||
use crate::config::com::read_config;
|
use crate::config::com::read_config;
|
||||||
use crate::disk::BUCKET_META_PREFIX;
|
use crate::disk::BUCKET_META_PREFIX;
|
||||||
use crate::error::Error as EcstoreError;
|
use crate::error::Error as EcstoreError;
|
||||||
use crate::store_api::ObjectInfo;
|
use crate::store_api::{ObjectIO, ObjectInfo};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use rustfs_filemeta::MrfReplicateEntry;
|
use rustfs_filemeta::MrfReplicateEntry;
|
||||||
use rustfs_filemeta::ReplicateDecision;
|
use rustfs_filemeta::ReplicateDecision;
|
||||||
@@ -976,7 +976,7 @@ impl<S: StorageAPI> ReplicationPool<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Load bucket resync metadata from disk
|
/// Load bucket resync metadata from disk
|
||||||
async fn load_bucket_resync_metadata<S: StorageAPI>(
|
async fn load_bucket_resync_metadata<S: ObjectIO>(
|
||||||
bucket: &str,
|
bucket: &str,
|
||||||
obj_api: Arc<S>,
|
obj_api: Arc<S>,
|
||||||
) -> Result<BucketReplicationResyncStatus, EcstoreError> {
|
) -> Result<BucketReplicationResyncStatus, EcstoreError> {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ use crate::event_notification::{EventArgs, send_event};
|
|||||||
use crate::global::GLOBAL_LocalNodeName;
|
use crate::global::GLOBAL_LocalNodeName;
|
||||||
use crate::global::get_global_bucket_monitor;
|
use crate::global::get_global_bucket_monitor;
|
||||||
use crate::set_disk::get_lock_acquire_timeout;
|
use crate::set_disk::get_lock_acquire_timeout;
|
||||||
use crate::store_api::{DeletedObject, HTTPRangeSpec, ObjectInfo, ObjectOptions, ObjectToDelete, WalkOptions};
|
use crate::store_api::{DeletedObject, HTTPRangeSpec, ObjectIO, ObjectInfo, ObjectOptions, ObjectToDelete, WalkOptions};
|
||||||
use crate::{StorageAPI, new_object_layer_fn};
|
use crate::{StorageAPI, new_object_layer_fn};
|
||||||
use aws_sdk_s3::error::{ProvideErrorMetadata, SdkError};
|
use aws_sdk_s3::error::{ProvideErrorMetadata, SdkError};
|
||||||
use aws_sdk_s3::operation::head_object::{HeadObjectError, HeadObjectOutput};
|
use aws_sdk_s3::operation::head_object::{HeadObjectError, HeadObjectOutput};
|
||||||
@@ -485,7 +485,7 @@ impl ReplicationResyncer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn mark_status<S: StorageAPI>(&self, status: ResyncStatusType, opts: ResyncOpts, obj_layer: Arc<S>) -> Result<()> {
|
pub async fn mark_status<S: ObjectIO>(&self, status: ResyncStatusType, opts: ResyncOpts, obj_layer: Arc<S>) -> Result<()> {
|
||||||
let bucket_status = {
|
let bucket_status = {
|
||||||
let mut status_map = self.status_map.write().await;
|
let mut status_map = self.status_map.write().await;
|
||||||
let now = OffsetDateTime::now_utc();
|
let now = OffsetDateTime::now_utc();
|
||||||
@@ -590,7 +590,7 @@ impl ReplicationResyncer {
|
|||||||
bucket_status.last_update = Some(now);
|
bucket_status.last_update = Some(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn persist_to_disk<S: StorageAPI>(&self, cancel_token: CancellationToken, api: Arc<S>) {
|
pub async fn persist_to_disk<S: ObjectIO>(&self, cancel_token: CancellationToken, api: Arc<S>) {
|
||||||
let mut interval = tokio::time::interval(RESYNC_TIME_INTERVAL);
|
let mut interval = tokio::time::interval(RESYNC_TIME_INTERVAL);
|
||||||
|
|
||||||
let mut last_update_times = HashMap::new();
|
let mut last_update_times = HashMap::new();
|
||||||
@@ -635,7 +635,7 @@ impl ReplicationResyncer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn resync_bucket_mark_status<S: StorageAPI>(&self, status: ResyncStatusType, opts: ResyncOpts, storage: Arc<S>) {
|
async fn resync_bucket_mark_status<S: ObjectIO>(&self, status: ResyncStatusType, opts: ResyncOpts, storage: Arc<S>) {
|
||||||
if let Err(err) = self.mark_status(status, opts.clone(), storage.clone()).await {
|
if let Err(err) = self.mark_status(status, opts.clone(), storage.clone()).await {
|
||||||
error!("Failed to mark resync status: {}", err);
|
error!("Failed to mark resync status: {}", err);
|
||||||
}
|
}
|
||||||
@@ -1026,7 +1026,7 @@ pub async fn get_heal_replicate_object_info(oi: &ObjectInfo, rcfg: &ReplicationC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn save_resync_status<S: StorageAPI>(
|
pub(crate) async fn save_resync_status<S: ObjectIO>(
|
||||||
bucket: &str,
|
bucket: &str,
|
||||||
status: &BucketReplicationResyncStatus,
|
status: &BucketReplicationResyncStatus,
|
||||||
api: Arc<S>,
|
api: Arc<S>,
|
||||||
|
|||||||
@@ -5,16 +5,16 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
|||||||
## Current Context
|
## Current Context
|
||||||
|
|
||||||
- Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660)
|
- Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660)
|
||||||
- Branch: `overtrue/arch-storage-api-bound-narrowing`
|
- Branch: `overtrue/arch-replication-resync-bounds`
|
||||||
- Baseline: `origin/main` at `6b86e3875c4912f3a7c27915b0bbd43399402847`
|
- Baseline: `origin/main` at `7191a3abae08918eedb117955280dc81e65450de`
|
||||||
- PR type for this branch: `dependency-migration`
|
- PR type for this branch: `dependency-migration`
|
||||||
- Runtime behavior changes: none.
|
- Runtime behavior changes: none.
|
||||||
- Rust code changes: narrow metadata helper generic bounds away from full
|
- Rust code changes: narrow replication resync metadata helper generic bounds
|
||||||
`StorageAPI` where helpers only need object I/O, object metadata/delete,
|
away from full `StorageAPI` where helpers only need object I/O.
|
||||||
bucket listing, object listing, or `StorageAdminApi`.
|
|
||||||
- CI/script changes: none.
|
- CI/script changes: none.
|
||||||
- Docs changes: record API-008 completion and the current bound-narrowing
|
- Docs changes: record API-009 completion and the current replication resync
|
||||||
context, verification evidence, and expert review outcomes.
|
metadata bound-narrowing context, verification evidence, and expert review
|
||||||
|
outcomes.
|
||||||
|
|
||||||
## Phase 0 Tasks
|
## Phase 0 Tasks
|
||||||
|
|
||||||
@@ -226,25 +226,35 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
|||||||
`new_ns_lock`, while admin inventory surfaces live only on
|
`new_ns_lock`, while admin inventory surfaces live only on
|
||||||
`StorageAdminApi`.
|
`StorageAdminApi`.
|
||||||
|
|
||||||
- [~] `API-009` Narrow metadata helper storage bounds.
|
- [x] `API-009` Narrow metadata helper storage bounds.
|
||||||
- Current branch slice: narrow server config, tier config, rebalance
|
- Completed slice: `rustfs/rustfs#3343` narrowed server config, tier config,
|
||||||
metadata, and startup metadata migration helper bounds away from full
|
rebalance metadata, and startup metadata migration helper bounds away from
|
||||||
`StorageAPI` when the helper only needs `ObjectIO`, `ObjectOperations`,
|
full `StorageAPI` when the helper only needs `ObjectIO`,
|
||||||
`BucketOperations`, `ListOperations`, or `StorageAdminApi`.
|
`ObjectOperations`, `BucketOperations`, `ListOperations`, or
|
||||||
|
`StorageAdminApi`.
|
||||||
- Acceptance: metadata helper contracts express the actual operation group
|
- Acceptance: metadata helper contracts express the actual operation group
|
||||||
they need, while callers and persistence behavior remain unchanged.
|
they need, while callers and persistence behavior remain unchanged.
|
||||||
- Must preserve: config/tier/rebalance serialized byte shapes, read/write
|
|
||||||
object names, legacy bucket/IAM migration normalization and skip behavior,
|
- [~] `API-010` Narrow replication resync metadata bounds.
|
||||||
lock behavior around rebalance metadata merge, dynamic storage-class lookup,
|
- Current branch slice: narrow replication resync status load/save/mark/persist
|
||||||
object APIs, scanner cache persistence, heal repair, replication
|
helper bounds away from full `StorageAPI` when the helper only needs
|
||||||
persistence, and storage hot paths.
|
`ObjectIO`.
|
||||||
|
- Acceptance: resync metadata helpers express object-I/O-only persistence
|
||||||
|
requirements, while replication execution, delete replication, multipart
|
||||||
|
replication, object lookups, and scheduling behavior remain on full
|
||||||
|
`StorageAPI` where needed.
|
||||||
|
- Must preserve: resync status serialization, resync metadata object paths,
|
||||||
|
in-memory status-map mutation order, stale-update rejection, periodic
|
||||||
|
persistence cadence, worker-token behavior, target replication decisions,
|
||||||
|
object replication, delete replication, multipart replication, scanner,
|
||||||
|
heal, and storage hot paths.
|
||||||
- Risk defense: do not move traits to `rustfs-storage-api`, do not remove
|
- Risk defense: do not move traits to `rustfs-storage-api`, do not remove
|
||||||
`StorageAPI`, do not alter helper bodies or storage options, and keep
|
`StorageAPI`, do not alter helper bodies or storage options, and do not
|
||||||
`save_rebalance_meta_with_merge` on full `StorageAPI` because it still needs
|
narrow replication execution paths that use object/list/multipart/delete
|
||||||
`new_ns_lock`.
|
operations beyond metadata persistence.
|
||||||
- Verification: focused compile/tests, migration guards, Rust risk scan, and
|
- Verification: focused compile/tests, migration guards, and Rust risk scan
|
||||||
required quality/architecture, migration-preservation, and
|
passed; required quality/architecture, migration-preservation, and
|
||||||
testing/verification review passed before push.
|
testing/verification review is pending before push.
|
||||||
|
|
||||||
## Phase 8 Background Controller Tasks
|
## Phase 8 Background Controller Tasks
|
||||||
|
|
||||||
@@ -269,8 +279,8 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
|||||||
|
|
||||||
## Next PRs
|
## Next PRs
|
||||||
|
|
||||||
1. `dependency-migration`: narrow metadata/helper bounds away from full
|
1. `dependency-migration`: narrow replication resync metadata helper bounds
|
||||||
`StorageAPI` where the helper only needs a specific operation trait.
|
away from full `StorageAPI` where the helper only needs `ObjectIO`.
|
||||||
2. `api-extraction`: move only the pure server-config model into
|
2. `api-extraction`: move only the pure server-config model into
|
||||||
rustfs-config as CFG-003.
|
rustfs-config as CFG-003.
|
||||||
3. `api-extraction`: keep the old rustfs_ecstore::config::* path with
|
3. `api-extraction`: keep the old rustfs_ecstore::config::* path with
|
||||||
@@ -286,9 +296,9 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
|||||||
|
|
||||||
| Expert | Status | Notes |
|
| Expert | Status | Notes |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Quality/architecture | pass | Confirmed the Rust diff only changes imports/generic bounds, the new operation-group bounds match actual calls, `StorageAPI` and `new_ns_lock` remain where needed, and no over-abstraction, naming regression, dependency reversal, or hot-path intrusion was found. |
|
| Quality/architecture | pass | Confirmed the Rust diff only adds the `ObjectIO` import and narrows resync metadata load/save/mark/persist helper bounds; helper bodies are unchanged, broader replication execution paths remain on `StorageAPI`, and no new abstraction or crate split was added. |
|
||||||
| Migration preservation | pass | Confirmed config/tier/rebalance byte shapes, object names, buckets, options, bucket/IAM normalization and skip behavior, dynamic storage-class lookup, and rebalance metadata merge locking remain unchanged. |
|
| Migration preservation | pass | Confirmed `read_config`/`save_config` already use the `ObjectIO` contract, while resync metadata serialization, object paths, storage options, status-map flow, and object/delete/multipart replication paths remain unchanged. |
|
||||||
| Testing/verification | pass | Confirmed the focused compile, config/tier/rebalance/bucket migration tests, migration guards, diff hygiene, and added-line Rust risk scan are sufficient; full pre-commit can be skipped under the current larger-granularity instruction. |
|
| Testing/verification | pass | Confirmed the focused compile, replication/resync tests, migration guards, diff hygiene, and added-line risk scan are sufficient for this generic-bound-only slice, so full pre-commit can be skipped under the current larger-granularity instruction. |
|
||||||
|
|
||||||
## Verification Notes
|
## Verification Notes
|
||||||
|
|
||||||
@@ -297,41 +307,40 @@ Passed:
|
|||||||
- `cargo check -p rustfs-ecstore`.
|
- `cargo check -p rustfs-ecstore`.
|
||||||
- `cargo fmt --all --check`.
|
- `cargo fmt --all --check`.
|
||||||
- `cargo check -p rustfs-storage-api -p rustfs-ecstore -p rustfs --lib`.
|
- `cargo check -p rustfs-storage-api -p rustfs-ecstore -p rustfs --lib`.
|
||||||
- `cargo test -p rustfs-ecstore config --lib`; 59 passed.
|
- `cargo test -p rustfs-ecstore replication --lib`; 58 passed.
|
||||||
- `cargo test -p rustfs-ecstore tier --lib`; 27 passed.
|
- `cargo test -p rustfs-ecstore resync --lib`; 31 passed.
|
||||||
- `cargo test -p rustfs-ecstore rebalance --lib`; 198 passed.
|
|
||||||
- `cargo test -p rustfs-ecstore bucket::migration --lib`; 2 passed.
|
|
||||||
- `./scripts/check_architecture_migration_rules.sh`.
|
- `./scripts/check_architecture_migration_rules.sh`.
|
||||||
- `./scripts/check_layer_dependencies.sh`.
|
- `./scripts/check_layer_dependencies.sh`.
|
||||||
- `./scripts/check_metrics_migration_refs.sh`.
|
- `./scripts/check_metrics_migration_refs.sh`.
|
||||||
- `./scripts/check_unsafe_code_allowances.sh`.
|
- `./scripts/check_unsafe_code_allowances.sh`.
|
||||||
- `git diff --check`.
|
- `git diff --check`.
|
||||||
- Rust code-quality scan on changed `.rs` files: broad full-file matches are
|
- Rust code-quality scan on changed `.rs` files, plus added-line scan for
|
||||||
pre-existing test/business-code patterns; added-line scan found no new
|
unwrap/expect, numeric casts, `Result<_, String>`, `Box<dyn Error>`,
|
||||||
unwrap/expect, numeric cast, `Result<_, String>`, `Box<dyn Error>`,
|
println/eprintln, and `Ordering::Relaxed`; broad full-file matches are
|
||||||
println/eprintln, or `Ordering::Relaxed`.
|
pre-existing touched-file patterns, and the added-line scan found no new
|
||||||
|
risky code patterns.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- Full pre-commit is intentionally skipped when the focused tests and guards
|
- Full pre-commit is intentionally skipped when the focused tests and guards
|
||||||
pass, per the current instruction to increase PR granularity.
|
pass, per the current instruction to increase PR granularity.
|
||||||
- This slice changes generic bounds and imports only; helper bodies, storage
|
- This slice changes generic bounds and imports only; helper bodies, storage
|
||||||
options, object names, and metadata normalization logic are unchanged.
|
options, object paths, and resync serialization logic are unchanged.
|
||||||
- `save_rebalance_meta_with_merge` intentionally still requires full
|
- Replication execution paths intentionally still require full `StorageAPI`
|
||||||
`StorageAPI` because it uses `new_ns_lock`.
|
where they use object/list/multipart/delete operations.
|
||||||
- No temporary compatibility shim was added.
|
- No temporary compatibility shim was added.
|
||||||
|
|
||||||
## Handoff Notes
|
## Handoff Notes
|
||||||
|
|
||||||
- Keep this API-009 slice as a `dependency-migration` PR that only narrows
|
- Keep this API-010 slice as a `dependency-migration` PR that only narrows
|
||||||
metadata/helper generic bounds for config, tier, rebalance, and startup
|
replication resync metadata helper generic bounds.
|
||||||
metadata migration helpers.
|
|
||||||
- Do not remove `StorageAPI` itself, object operation traits, or
|
- Do not remove `StorageAPI` itself, object operation traits, or
|
||||||
`new_ns_lock` in this PR.
|
`new_ns_lock` in this PR.
|
||||||
- Do not move traits into `rustfs-storage-api` or introduce new compatibility
|
- Do not move traits into `rustfs-storage-api` or introduce new compatibility
|
||||||
shims in this PR.
|
shims in this PR.
|
||||||
- Do not alter config/tier/rebalance serialized byte shapes, legacy bucket/IAM
|
- Do not alter resync status serialization, metadata object paths, stale-update
|
||||||
migration normalization, object names, storage options, scanner cache writes,
|
rejection, status-map mutation order, periodic persistence cadence, worker
|
||||||
heal object repair, object APIs, replication persistence, or storage hot-path
|
token behavior, replication execution, delete replication, multipart
|
||||||
consumers in this PR.
|
replication, scanner cache writes, heal object repair, object APIs, or storage
|
||||||
|
hot-path consumers in this PR.
|
||||||
- Do not add temporary compatibility code unless a matching
|
- Do not add temporary compatibility code unless a matching
|
||||||
`RUSTFS_COMPAT_TODO(<task-id>)` marker and cleanup-register entry are added.
|
`RUSTFS_COMPAT_TODO(<task-id>)` marker and cleanup-register entry are added.
|
||||||
|
|||||||
Reference in New Issue
Block a user