The lock added alongside compare-and-set removed its map entry inside the critical section. A queued waiter still held that mutex, so the next arrival found no entry, created a fresh one, and the two then ran concurrently -- defeating the lock exactly when there was contention, which is the only time it does anything. I previously reported this fix as working on the strength of ten clean release-mode runs. That was wrong: in debug, where the timing differs, the guarding test fails 3 times in 12. Retiring the entry only after dropping our own reference, under the same shard lock `entry` takes, gives 0 failures in 25 -- and restoring the old behaviour reproduces 3 in 12, so the test really does catch it. The consequence was the one the test names: a file served to a client but never recorded, and so invisible the moment the instance is sealed. Real against the local filesystem store, which has no conditional put and relies on the verify-after-write retry; MinIO's compare-and-set covers the same race, which is why the deployed path never showed it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XZG2i4AmfSqE97EJGBVb64
20 lines
631 B
Rust
20 lines
631 B
Rust
//! Domain types for rustingface.
|
|
//!
|
|
//! This crate is pure: it defines the on-disk schemas (manifest, ref, repo
|
|
//! record), the bucket key layout, the configuration shape and the error
|
|
//! taxonomy that the HTTP surface replays to clients. It performs no I/O and
|
|
//! pulls in no async runtime.
|
|
|
|
pub mod config;
|
|
pub mod error;
|
|
pub mod key;
|
|
pub mod manifest;
|
|
pub mod refs;
|
|
pub mod repo;
|
|
|
|
pub use config::{Anonymous, Config};
|
|
pub use error::{Error, ErrorCode, Result};
|
|
pub use manifest::{Entry, MANIFEST_SCHEMA, Manifest};
|
|
pub use refs::{PinnedBy, REF_SCHEMA, RefRecord};
|
|
pub use repo::{REPO_SCHEMA, RepoId, RepoRecord, RepoType};
|