diff --git a/design_doc.md b/design_doc.md index dd9f19b..6d5c13b 100644 --- a/design_doc.md +++ b/design_doc.md @@ -32,7 +32,6 @@ We choose RocksDB as the database in the catalog to store metadata. It is a fast ## Design Rationale -An explanation of why you chose the given design. Your justification should discuss issues related to (1) correctness, (2) performance, (3) engineering complexity/maintainability, and (4) testing. It should also include a brief discussion of the other implementations that you considered and why they were deemed inferior. Most design decisions were made with the assumption that we do not have any schema updates and writes are infrequent with bulk data #### Database @@ -42,7 +41,6 @@ We contemplated two embedded database candidates for catalog service: SQLite and 1. Better concurrency control: SQLite locks the entire database when dealing with concurrency writing, whereas RocksDB supports snapshots. 2. Flexibility: RocksDB provides more configuration options. 3. Scalability: RocksDB stores data in different partitions, whereas SQLite stores data in one single file, which isn’t ideal for scalability. -4. Storage: RocksDB uses key-value storage, which is good for intensive write operations. In short, RocksDB would provide better performance and concurrency control when we deal with write-intensive workloads. #### Why a key-value store? @@ -142,6 +140,7 @@ Duration [total, attack, wait] 9.9895398s, 9.9890283s, 511.5µs Latencies [mean, 50, 95, 99, max] 1.883553ms, 1.191091ms, 5.006752ms, 8.196381ms, 43.6933ms ``` ![](./test_results/windows/list_namespace.png) + #### List Tables API ``` Requests [total, rate, throughput] 9992, 999.50, 999.50 @@ -149,6 +148,7 @@ Duration [total, attack, wait] 9.9970348s, 9.9970348s, 0s Latencies [mean, 50, 95, 99, max] 971.232µs, 973.659µs, 1.978657ms, 3.292131ms, 45.7625ms ``` ![](./test_results/windows/list_table.png) + #### Random Testing ``` Requests [total, rate, throughput] 59995, 1000.02, 1000.02 diff --git a/src/dto/errors.rs b/src/dto/errors.rs deleted file mode 100644 index 7811a66..0000000 --- a/src/dto/errors.rs +++ /dev/null @@ -1,137 +0,0 @@ -use serde::{Deserialize, Serialize}; -use std::fmt::Debug; - -#[derive(Debug, Deserialize, Serialize)] -pub struct NamespaceNotFoundError { - pub message: String, -} - -impl From for IcebergErrorResponse { - fn from(err: NamespaceNotFoundError) -> Self { - IcebergErrorResponse { - error: ErrorModel { - message: err.message, - r#type: "NamespaceNotFound".to_string(), - code: 404, - stack: None, - }, - } - } -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct ErrorModel { - pub message: String, - pub r#type: String, // Use `r#type` to avoid keyword conflict - pub code: u16, - #[serde(skip_serializing_if = "Option::is_none")] - pub stack: Option>, -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct IcebergErrorResponse { - pub error: ErrorModel, -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct CommonResponse { - pub error: Option, -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct BadRequestErrorResponse(pub CommonResponse); - -#[derive(Debug, Deserialize, Serialize)] -pub struct UnsupportedOperationResponse(pub CommonResponse); - -#[derive(Debug, Deserialize, Serialize)] -pub struct ServiceUnavailableResponse(pub CommonResponse); - -#[derive(Debug, Deserialize, Serialize)] -pub struct ServerErrorResponse(pub CommonResponse); - -#[derive(Debug, Deserialize, Serialize)] -pub enum ErrorTypes { - BadRequest(String), - Unauthorized(String), - ServiceUnavailable(String), - ServerError(String), - NamespaceNotFound(String), -} - -impl std::fmt::Display for ErrorTypes { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ErrorTypes::BadRequest(msg) => write!(f, "Bad Request: {}", msg), - ErrorTypes::Unauthorized(msg) => write!(f, "Unauthorized: {}", msg), - ErrorTypes::ServiceUnavailable(msg) => write!(f, "Service Unavailable: {}", msg), - ErrorTypes::ServerError(msg) => write!(f, "Internal Server Error: {}", msg), - ErrorTypes::NamespaceNotFound(msg) => write!(f, "Namespace Not Found: {}", msg), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use serde_json::{json, Value}; - - #[test] - fn test_namespace_not_found_error() { - let err = NamespaceNotFoundError { - message: "Namespace 'test' not found".to_string(), - }; - let iceberg_err: IcebergErrorResponse = err.into(); - - assert_eq!(iceberg_err.error.message, "Namespace 'test' not found"); - assert_eq!(iceberg_err.error.r#type, "NamespaceNotFound"); - assert_eq!(iceberg_err.error.code, 404); - assert!(iceberg_err.error.stack.is_none()); - } - - #[test] - fn test_error_model_deserialization() { - let json_str = r#"{ - "message": "Bad request", - "type": "BadRequest", - "code": 400, - "stack": null - }"#; - - let error_model: ErrorModel = serde_json::from_str(json_str).unwrap(); - - assert_eq!(error_model.message, "Bad request"); - assert_eq!(error_model.r#type, "BadRequest"); - assert_eq!(error_model.code, 400); - assert!(error_model.stack.is_none()); - } - - #[test] - fn test_error_types_display() { - let bad_request = ErrorTypes::BadRequest("Invalid request body".to_string()); - let unauthorized = ErrorTypes::Unauthorized("Missing authentication token".to_string()); - let service_unavailable = - ErrorTypes::ServiceUnavailable("Server is under maintenance".to_string()); - let server_error = ErrorTypes::ServerError("Internal server error".to_string()); - let namespace_not_found = - ErrorTypes::NamespaceNotFound("Namespace 'test' not found".to_string()); - - assert_eq!(bad_request.to_string(), "Bad Request: Invalid request body"); - assert_eq!( - unauthorized.to_string(), - "Unauthorized: Missing authentication token" - ); - assert_eq!( - service_unavailable.to_string(), - "Service Unavailable: Server is under maintenance" - ); - assert_eq!( - server_error.to_string(), - "Internal Server Error: Internal server error" - ); - assert_eq!( - namespace_not_found.to_string(), - "Namespace Not Found: Namespace 'test' not found" - ); - } -} diff --git a/src/dto/mod.rs b/src/dto/mod.rs index bf04b8b..98f2086 100644 --- a/src/dto/mod.rs +++ b/src/dto/mod.rs @@ -1,5 +1,4 @@ pub mod column_data; -pub mod errors; pub mod namespace_data; pub mod rename_request; pub mod set_namespace_properties_req; diff --git a/src/handlers/namespace_handler.rs b/src/handlers/namespace_handler.rs index abacbf0..f7a365f 100644 --- a/src/handlers/namespace_handler.rs +++ b/src/handlers/namespace_handler.rs @@ -143,9 +143,6 @@ mod tests { use tempfile::tempdir; #[tokio::test] async fn test_namespace_endpoints() { - let dir = tempdir().unwrap(); - let db = Database::open(dir.path()).unwrap(); - let db = Arc::new(Mutex::new(db)); let repo = Arc::new(NamespaceRepository::new(Arc::new(Mutex::new( Database::open(tempdir().unwrap().path()).unwrap(), ))));