refactor(lock): restructure lock crate, remove unused modules and clarify directory layout

- Remove unused core/rwlock.rs and manager/ modules (ManagerFactory, LifecycleManager, NamespaceManager)
- Move all lock-related code into crates/lock/src with clear submodules: client, core, utils, etc.
- Ensure only necessary files and APIs are exposed, improve maintainability
- No functional logic change, pure structure and cleanup refactor

Signed-off-by: dandan <dandan@dandandeMac-Studio.local>
This commit is contained in:
dandan
2025-07-04 17:28:18 +08:00
committed by junxiang Mu
parent 1b48934f47
commit 4ccdeb9d2a
28 changed files with 6191 additions and 2466 deletions
+257
View File
@@ -0,0 +1,257 @@
// Copyright 2024 RustFS Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::time::Duration;
use thiserror::Error;
/// Lock operation related error types
#[derive(Error, Debug)]
pub enum LockError {
/// Lock acquisition timeout
#[error("Lock acquisition timeout for resource '{resource}' after {timeout:?}")]
Timeout { resource: String, timeout: Duration },
/// Resource not found
#[error("Resource not found: {resource}")]
ResourceNotFound { resource: String },
/// Permission denied
#[error("Permission denied: {reason}")]
PermissionDenied { reason: String },
/// Network error
#[error("Network error: {message}")]
Network {
message: String,
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
/// Internal error
#[error("Internal error: {message}")]
Internal { message: String },
/// Resource is already locked
#[error("Resource '{resource}' is already locked by {owner}")]
AlreadyLocked { resource: String, owner: String },
/// Invalid lock handle
#[error("Invalid lock handle: {handle_id}")]
InvalidHandle { handle_id: String },
/// Configuration error
#[error("Configuration error: {message}")]
Configuration { message: String },
/// Serialization error
#[error("Serialization error: {message}")]
Serialization {
message: String,
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
/// Deserialization error
#[error("Deserialization error: {message}")]
Deserialization {
message: String,
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
}
impl LockError {
/// Create timeout error
pub fn timeout(resource: impl Into<String>, timeout: Duration) -> Self {
Self::Timeout {
resource: resource.into(),
timeout,
}
}
/// Create resource not found error
pub fn resource_not_found(resource: impl Into<String>) -> Self {
Self::ResourceNotFound {
resource: resource.into(),
}
}
/// Create permission denied error
pub fn permission_denied(reason: impl Into<String>) -> Self {
Self::PermissionDenied { reason: reason.into() }
}
/// Create network error
pub fn network(message: impl Into<String>, source: impl std::error::Error + Send + Sync + 'static) -> Self {
Self::Network {
message: message.into(),
source: Box::new(source),
}
}
/// Create internal error
pub fn internal(message: impl Into<String>) -> Self {
Self::Internal { message: message.into() }
}
/// Create lock already locked error
pub fn already_locked(resource: impl Into<String>, owner: impl Into<String>) -> Self {
Self::AlreadyLocked {
resource: resource.into(),
owner: owner.into(),
}
}
/// Create invalid handle error
pub fn invalid_handle(handle_id: impl Into<String>) -> Self {
Self::InvalidHandle {
handle_id: handle_id.into(),
}
}
/// Create configuration error
pub fn configuration(message: impl Into<String>) -> Self {
Self::Configuration { message: message.into() }
}
/// Create serialization error
pub fn serialization(message: impl Into<String>, source: impl std::error::Error + Send + Sync + 'static) -> Self {
Self::Serialization {
message: message.into(),
source: Box::new(source),
}
}
/// Create deserialization error
pub fn deserialization(message: impl Into<String>, source: impl std::error::Error + Send + Sync + 'static) -> Self {
Self::Deserialization {
message: message.into(),
source: Box::new(source),
}
}
/// Check if it is a retryable error
pub fn is_retryable(&self) -> bool {
matches!(self, Self::Timeout { .. } | Self::Network { .. } | Self::Internal { .. })
}
/// Check if it is a fatal error
pub fn is_fatal(&self) -> bool {
matches!(
self,
Self::ResourceNotFound { .. } | Self::PermissionDenied { .. } | Self::Configuration { .. }
)
}
}
/// Lock operation Result type
pub type Result<T> = std::result::Result<T, LockError>;
/// Convert from std::io::Error
impl From<std::io::Error> for LockError {
fn from(err: std::io::Error) -> Self {
match err.kind() {
std::io::ErrorKind::TimedOut => Self::Internal {
message: "IO timeout".to_string(),
},
std::io::ErrorKind::NotFound => Self::ResourceNotFound {
resource: "unknown".to_string(),
},
std::io::ErrorKind::PermissionDenied => Self::PermissionDenied { reason: err.to_string() },
_ => Self::Internal {
message: err.to_string(),
},
}
}
}
/// Convert from serde_json::Error
impl From<serde_json::Error> for LockError {
fn from(err: serde_json::Error) -> Self {
if err.is_io() {
Self::network("JSON serialization IO error", err)
} else if err.is_syntax() {
Self::deserialization("JSON syntax error", err)
} else if err.is_data() {
Self::deserialization("JSON data error", err)
} else {
Self::serialization("JSON serialization error", err)
}
}
}
/// Convert from tonic::Status
impl From<tonic::Status> for LockError {
fn from(status: tonic::Status) -> Self {
match status.code() {
tonic::Code::DeadlineExceeded => Self::Internal {
message: "gRPC deadline exceeded".to_string(),
},
tonic::Code::NotFound => Self::ResourceNotFound {
resource: "unknown".to_string(),
},
tonic::Code::PermissionDenied => Self::PermissionDenied {
reason: status.message().to_string(),
},
tonic::Code::Unavailable => Self::Network {
message: "gRPC service unavailable".to_string(),
source: Box::new(status),
},
_ => Self::Internal {
message: status.message().to_string(),
},
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_creation() {
let timeout_err = LockError::timeout("test-resource", Duration::from_secs(5));
assert!(matches!(timeout_err, LockError::Timeout { .. }));
let not_found_err = LockError::resource_not_found("missing-resource");
assert!(matches!(not_found_err, LockError::ResourceNotFound { .. }));
let permission_err = LockError::permission_denied("insufficient privileges");
assert!(matches!(permission_err, LockError::PermissionDenied { .. }));
}
#[test]
fn test_error_retryable() {
let timeout_err = LockError::timeout("test", Duration::from_secs(1));
assert!(timeout_err.is_retryable());
let network_err = LockError::network("connection failed", std::io::Error::new(std::io::ErrorKind::ConnectionRefused, ""));
assert!(network_err.is_retryable());
let not_found_err = LockError::resource_not_found("test");
assert!(!not_found_err.is_retryable());
}
#[test]
fn test_error_fatal() {
let not_found_err = LockError::resource_not_found("test");
assert!(not_found_err.is_fatal());
let permission_err = LockError::permission_denied("test");
assert!(permission_err.is_fatal());
let timeout_err = LockError::timeout("test", Duration::from_secs(1));
assert!(!timeout_err.is_fatal());
}
}