docs: add missing backticks in documentation

this improve readability of documentation.
enable associated clippy lint `doc_markdown`
This commit is contained in:
Gwen Lg
2026-01-25 23:46:05 +01:00
committed by Alex
parent 6cde00073f
commit 08fd6e659f
58 changed files with 175 additions and 174 deletions
+2 -1
View File
@@ -181,4 +181,5 @@ opt-level = 3
strip = "debuginfo" strip = "debuginfo"
[workspace.lints.clippy] [workspace.lints.clippy]
# custom configuration # pedantic lints configuration
doc_markdown = "warn"
+1 -1
View File
@@ -77,7 +77,7 @@ pub enum Endpoint {
impl Endpoint { impl Endpoint {
/// Determine which S3 endpoint a request is for using the request, and a bucket which was /// Determine which S3 endpoint a request is for using the request, and a bucket which was
/// possibly extracted from the Host header. /// possibly extracted from the Host header.
/// Returns Self plus bucket name, if endpoint is not Endpoint::ListBuckets /// Returns Self plus bucket name, if endpoint is not `Endpoint::ListBuckets`
pub fn from_request<T>(req: &Request<T>) -> Result<Self, Error> { pub fn from_request<T>(req: &Request<T>) -> Result<Self, Error> {
let uri = req.uri(); let uri = req.uri();
let path = uri.path(); let path = uri.path();
+1 -1
View File
@@ -79,7 +79,7 @@ pub enum Endpoint {
impl Endpoint { impl Endpoint {
/// Determine which S3 endpoint a request is for using the request, and a bucket which was /// Determine which S3 endpoint a request is for using the request, and a bucket which was
/// possibly extracted from the Host header. /// possibly extracted from the Host header.
/// Returns Self plus bucket name, if endpoint is not Endpoint::ListBuckets /// Returns Self plus bucket name, if endpoint is not `Endpoint::ListBuckets`
pub fn from_request<T>(req: &Request<T>) -> Result<Self, Error> { pub fn from_request<T>(req: &Request<T>) -> Result<Self, Error> {
let uri = req.uri(); let uri = req.uri();
let path = uri.path(); let path = uri.path();
+1 -1
View File
@@ -15,7 +15,7 @@ use crate::Authorization;
impl AdminApiRequest { impl AdminApiRequest {
/// Determine which S3 endpoint a request is for using the request, and a bucket which was /// Determine which S3 endpoint a request is for using the request, and a bucket which was
/// possibly extracted from the Host header. /// possibly extracted from the Host header.
/// Returns Self plus bucket name, if endpoint is not Endpoint::ListBuckets /// Returns Self plus bucket name, if endpoint is not `Endpoint::ListBuckets`
pub async fn from_request(req: Request<IncomingBody>) -> Result<Self, Error> { pub async fn from_request(req: Request<IncomingBody>) -> Result<Self, Error> {
let uri = req.uri().clone(); let uri = req.uri().clone();
let path = uri.path(); let path = uri.path();
+4 -4
View File
@@ -142,10 +142,10 @@ impl TryFrom<HelperError> for CommonError {
} }
} }
/// This function converts HelperErrors into CommonErrors, /// This function converts `HelperErrors` into `CommonErrors`,
/// for variants that exist in CommonError. /// for variants that exist in `CommonError`.
/// This is used for helper functions that might return InvalidBucketName /// This is used for helper functions that might return `InvalidBucketName`
/// or NoSuchBucket for instance, and we want to pass that error /// or `NoSuchBucket` for instance, and we want to pass that error
/// up to our caller. /// up to our caller.
pub fn pass_helper_error(err: HelperError) -> CommonError { pub fn pass_helper_error(err: HelperError) -> CommonError {
match CommonError::try_from(err) { match CommonError::try_from(err) {
+2 -2
View File
@@ -97,7 +97,7 @@ impl ReturnFormat {
} }
} }
/// Handle ReadItem request /// Handle `ReadItem` request
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub async fn handle_read_item( pub async fn handle_read_item(
ctx: ReqCtx, ctx: ReqCtx,
@@ -201,7 +201,7 @@ pub async fn handle_delete_item(
.body(empty_body())?) .body(empty_body())?)
} }
/// Handle ReadItem request /// Handle `ReadItem` request
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub async fn handle_poll_item( pub async fn handle_poll_item(
ctx: ReqCtx, ctx: ReqCtx,
+1 -1
View File
@@ -1,6 +1,6 @@
//! Utility module for retrieving ranges of items in Garage tables //! Utility module for retrieving ranges of items in Garage tables
//! Implements parameters (prefix, start, end, limit) as specified //! Implements parameters (prefix, start, end, limit) as specified
//! for endpoints ReadIndex, ReadBatch and DeleteBatch //! for endpoints `ReadIndex`, `ReadBatch` and `DeleteBatch`
use std::sync::Arc; use std::sync::Arc;
+1 -1
View File
@@ -53,7 +53,7 @@ pub enum Endpoint {
impl Endpoint { impl Endpoint {
/// Determine which S3 endpoint a request is for using the request, and a bucket which was /// Determine which S3 endpoint a request is for using the request, and a bucket which was
/// possibly extracted from the Host header. /// possibly extracted from the Host header.
/// Returns Self plus bucket name, if endpoint is not Endpoint::ListBuckets /// Returns Self plus bucket name, if endpoint is not `Endpoint::ListBuckets`
pub fn from_request<T>(req: &Request<T>) -> Result<(Self, String), Error> { pub fn from_request<T>(req: &Request<T>) -> Result<(Self, String), Error> {
let uri = req.uri(); let uri = req.uri();
let path = uri.path().trim_start_matches('/'); let path = uri.path().trim_start_matches('/');
+2 -2
View File
@@ -50,11 +50,11 @@ pub enum Error {
#[error("Parts given to CompleteMultipartUpload do not match uploaded parts")] #[error("Parts given to CompleteMultipartUpload do not match uploaded parts")]
InvalidPart, InvalidPart,
/// Parts given to CompleteMultipartUpload were not in ascending order /// Parts given to `CompleteMultipartUpload` were not in ascending order
#[error("Parts given to CompleteMultipartUpload were not in ascending order")] #[error("Parts given to CompleteMultipartUpload were not in ascending order")]
InvalidPartOrder, InvalidPartOrder,
/// In CompleteMultipartUpload: not enough data /// In `CompleteMultipartUpload`: not enough data
/// (here we are more lenient than AWS S3) /// (here we are more lenient than AWS S3)
#[error("Proposed upload is smaller than the minimum allowed object size")] #[error("Proposed upload is smaller than the minimum allowed object size")]
EntityTooSmall, EntityTooSmall,
+1 -1
View File
@@ -939,7 +939,7 @@ fn common_prefix<'a>(object: &'a Object, query: &ListQueryCommon) -> Option<&'a
} }
} }
/// URIencode a value if needed /// `URIencode` a value if needed
fn uriencode_maybe(s: &str, yes: bool) -> s3_xml::Value { fn uriencode_maybe(s: &str, yes: bool) -> s3_xml::Value {
if yes { if yes {
s3_xml::Value(uri_encode(s, true)) s3_xml::Value(uri_encode(s, true))
+1 -1
View File
@@ -309,7 +309,7 @@ pub enum Endpoint {
impl Endpoint { impl Endpoint {
/// Determine which S3 endpoint a request is for using the request, and a bucket which was /// Determine which S3 endpoint a request is for using the request, and a bucket which was
/// possibly extracted from the Host header. /// possibly extracted from the Host header.
/// Returns Self plus bucket name, if endpoint is not Endpoint::ListBuckets /// Returns Self plus bucket name, if endpoint is not `Endpoint::ListBuckets`
pub fn from_request<T>( pub fn from_request<T>(
req: &Request<T>, req: &Request<T>,
bucket: Option<String>, bucket: Option<String>,
+1 -1
View File
@@ -21,7 +21,7 @@ pub(crate) struct DataLayout {
pub(crate) data_dirs: Vec<DataDir>, pub(crate) data_dirs: Vec<DataDir>,
markers: HashMap<PathBuf, String>, markers: HashMap<PathBuf, String>,
/// Primary storage location (index in data_dirs) for each partition /// Primary storage location (index in `data_dirs`) for each partition
/// = the location where the data is supposed to be, blocks are always /// = the location where the data is supposed to be, blocks are always
/// written there (copies in other dirs may be deleted if they exist) /// written there (copies in other dirs may be deleted if they exist)
pub(crate) part_prim: Vec<Idx>, pub(crate) part_prim: Vec<Idx>,
+1 -1
View File
@@ -6,7 +6,7 @@ use opentelemetry::{global, metrics::*};
use garage_db as db; use garage_db as db;
/// TableMetrics reference all counter used for metrics /// `TableMetrics` reference all counter used for metrics
pub struct BlockManagerMetrics { pub struct BlockManagerMetrics {
pub(crate) _compression_level: ValueObserver<u64>, pub(crate) _compression_level: ValueObserver<u64>,
pub(crate) _rc_size: ValueObserver<u64>, pub(crate) _rc_size: ValueObserver<u64>,
+3 -3
View File
@@ -136,14 +136,14 @@ impl BlockRc {
pub(crate) enum RcEntry { pub(crate) enum RcEntry {
/// Present: the block has `count` references, with `count` > 0. /// Present: the block has `count` references, with `count` > 0.
/// ///
/// This is stored as u64::to_be_bytes(count) /// This is stored as `u64::to_be_bytes(count)`
Present { count: u64 }, Present { count: u64 },
/// Deletable: the block has zero references, and can be deleted /// Deletable: the block has zero references, and can be deleted
/// once time (returned by now_msec) is larger than at_time /// once time (returned by `now_msec`) is larger than `at_time`
/// (in millis since Unix epoch) /// (in millis since Unix epoch)
/// ///
/// This is stored as [0u8; 8] followed by u64::to_be_bytes(at_time), /// This is stored as [0u8; 8] followed by `u64::to_be_bytes(at_time)`,
/// (this allows for the data format to be backwards compatible with /// (this allows for the data format to be backwards compatible with
/// previous Garage versions that didn't have this intermediate state) /// previous Garage versions that didn't have this intermediate state)
Deletable { at_time: u64 }, Deletable { at_time: u64 },
+1 -1
View File
@@ -7,7 +7,7 @@ use garage_db::*;
/// K2V command line interface /// K2V command line interface
#[derive(StructOpt, Debug)] #[derive(StructOpt, Debug)]
pub struct ConvertDbOpt { pub struct ConvertDbOpt {
/// Input database path (not the same as metadata_dir, see /// Input database path (not the same as `metadata_dir`, see
/// <https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/#db_engine> /// <https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/#db_engine>
#[structopt(short = "i")] #[structopt(short = "i")]
input_path: PathBuf, input_path: PathBuf,
+8 -8
View File
@@ -71,7 +71,7 @@ pub enum Command {
/// The result is printed to `stdout` in JSON format. /// The result is printed to `stdout` in JSON format.
#[structopt(name = "json-api", version = garage_version())] #[structopt(name = "json-api", version = garage_version())]
JsonApi { JsonApi {
/// The admin API endpoint to invoke, e.g. GetClusterStatus /// The admin API endpoint to invoke, e.g. `GetClusterStatus`
endpoint: String, endpoint: String,
/// The JSON payload, or `-` to read from `stdin` /// The JSON payload, or `-` to read from `stdin`
#[structopt(default_value = "null")] #[structopt(default_value = "null")]
@@ -475,7 +475,7 @@ pub struct KeyNewOpt {
#[structopt(default_value = "Unnamed key")] #[structopt(default_value = "Unnamed key")]
pub name: String, pub name: String,
/// Set an expiration time for the access key /// Set an expiration time for the access key
/// (see docs.rs/parse_duration for date format) /// (see `docs.rs/parse_duration` for date format)
#[structopt(long = "expires-in")] #[structopt(long = "expires-in")]
pub expires_in: Option<String>, pub expires_in: Option<String>,
} }
@@ -486,7 +486,7 @@ pub struct KeySetOpt {
pub key_pattern: String, pub key_pattern: String,
/// Set an expiration time for the access key /// Set an expiration time for the access key
/// (see docs.rs/parse_duration for date format) /// (see `docs.rs/parse_duration` for date format)
#[structopt(long = "expires-in")] #[structopt(long = "expires-in")]
pub expires_in: Option<String>, pub expires_in: Option<String>,
/// Set the access key to never expire /// Set the access key to never expire
@@ -518,7 +518,7 @@ pub struct KeyPermOpt {
/// ID or name of the key /// ID or name of the key
pub key_pattern: String, pub key_pattern: String,
/// Flag that allows key to create buckets using S3's CreateBucket call /// Flag that allows key to create buckets using S3's `CreateBucket` call
#[structopt(long = "create-bucket")] #[structopt(long = "create-bucket")]
pub create_bucket: bool, pub create_bucket: bool,
} }
@@ -597,12 +597,12 @@ pub enum AdminTokenOperation {
pub struct AdminTokenCreateOp { pub struct AdminTokenCreateOp {
/// Set a name for the token /// Set a name for the token
pub name: Option<String>, pub name: Option<String>,
/// Set an expiration time for the token (see docs.rs/parse_duration for date /// Set an expiration time for the token (see `docs.rs/parse_duration` for date
/// format) /// format)
#[structopt(long = "expires-in")] #[structopt(long = "expires-in")]
pub expires_in: Option<String>, pub expires_in: Option<String>,
/// Set a limited scope for the token, as a comma-separated list of /// Set a limited scope for the token, as a comma-separated list of
/// admin API functions (e.g. GetClusterStatus, etc.). The default scope /// admin API functions (e.g. `GetClusterStatus`, etc.). The default scope
/// is `*`, which allows access to all admin API functions. /// is `*`, which allows access to all admin API functions.
/// Note that granting a scope that allows `CreateAdminToken` or /// Note that granting a scope that allows `CreateAdminToken` or
/// `UpdateAdminToken` allows for privilege escalation, and is therefore /// `UpdateAdminToken` allows for privilege escalation, and is therefore
@@ -619,7 +619,7 @@ pub struct AdminTokenSetOp {
/// Name or prefix of the ID of the token to modify /// Name or prefix of the ID of the token to modify
pub api_token: String, pub api_token: String,
/// Set an expiration time for the token (see docs.rs/parse_duration for date /// Set an expiration time for the token (see `docs.rs/parse_duration` for date
/// format) /// format)
#[structopt(long = "expires-in")] #[structopt(long = "expires-in")]
pub expires_in: Option<String>, pub expires_in: Option<String>,
@@ -628,7 +628,7 @@ pub struct AdminTokenSetOp {
pub never_expires: bool, pub never_expires: bool,
/// Set a limited scope for the token, as a comma-separated list of /// Set a limited scope for the token, as a comma-separated list of
/// admin API functions (e.g. GetClusterStatus, etc.), or `*` to allow /// admin API functions (e.g. `GetClusterStatus`, etc.), or `*` to allow
/// all admin API functions. /// all admin API functions.
/// Use `--scope=+Scope1,Scope2` to add scopes to the existing list, /// Use `--scope=+Scope1,Scope2` to add scopes to the existing list,
/// and `--scope=-Scope1,Scope2` to remove scopes from the existing list. /// and `--scope=-Scope1,Scope2` to remove scopes from the existing list.
+6 -6
View File
@@ -17,32 +17,32 @@ pub struct Secrets {
)] )]
pub allow_world_readable_secrets: Option<bool>, pub allow_world_readable_secrets: Option<bool>,
/// RPC secret network key, used to replace rpc_secret in config.toml when running the /// RPC secret network key, used to replace `rpc_secret` in config.toml when running the
/// daemon or doing admin operations /// daemon or doing admin operations
#[structopt(short = "s", long = "rpc-secret", env = "GARAGE_RPC_SECRET")] #[structopt(short = "s", long = "rpc-secret", env = "GARAGE_RPC_SECRET")]
pub rpc_secret: Option<String>, pub rpc_secret: Option<String>,
/// RPC secret network key, used to replace rpc_secret in config.toml and rpc-secret /// RPC secret network key, used to replace `rpc_secret` in config.toml and rpc-secret
/// when running the daemon or doing admin operations /// when running the daemon or doing admin operations
#[structopt(long = "rpc-secret-file", env = "GARAGE_RPC_SECRET_FILE")] #[structopt(long = "rpc-secret-file", env = "GARAGE_RPC_SECRET_FILE")]
pub rpc_secret_file: Option<PathBuf>, pub rpc_secret_file: Option<PathBuf>,
/// Admin API authentication token, replaces admin.admin_token in config.toml when /// Admin API authentication token, replaces `admin.admin_token` in config.toml when
/// running the Garage daemon /// running the Garage daemon
#[structopt(long = "admin-token", env = "GARAGE_ADMIN_TOKEN")] #[structopt(long = "admin-token", env = "GARAGE_ADMIN_TOKEN")]
pub admin_token: Option<String>, pub admin_token: Option<String>,
/// Admin API authentication token file path, replaces admin.admin_token in config.toml /// Admin API authentication token file path, replaces `admin.admin_token` in config.toml
/// and admin-token when running the Garage daemon /// and admin-token when running the Garage daemon
#[structopt(long = "admin-token-file", env = "GARAGE_ADMIN_TOKEN_FILE")] #[structopt(long = "admin-token-file", env = "GARAGE_ADMIN_TOKEN_FILE")]
pub admin_token_file: Option<PathBuf>, pub admin_token_file: Option<PathBuf>,
/// Metrics API authentication token, replaces admin.metrics_token in config.toml when /// Metrics API authentication token, replaces `admin.metrics_token` in config.toml when
/// running the Garage daemon /// running the Garage daemon
#[structopt(long = "metrics-token", env = "GARAGE_METRICS_TOKEN")] #[structopt(long = "metrics-token", env = "GARAGE_METRICS_TOKEN")]
pub metrics_token: Option<String>, pub metrics_token: Option<String>,
/// Metrics API authentication token file path, replaces admin.metrics_token in config.toml /// Metrics API authentication token file path, replaces `admin.metrics_token` in config.toml
/// and metrics-token when running the Garage daemon /// and metrics-token when running the Garage daemon
#[structopt(long = "metrics-token-file", env = "GARAGE_METRICS_TOKEN_FILE")] #[structopt(long = "metrics-token-file", env = "GARAGE_METRICS_TOKEN_FILE")]
pub metrics_token_file: Option<PathBuf>, pub metrics_token_file: Option<PathBuf>,
+1 -1
View File
@@ -75,7 +75,7 @@ impl Context {
bucket_name bucket_name
} }
/// Build a K2vClient for a given bucket /// Build a `K2vClient` for a given bucket
#[cfg(feature = "k2v")] #[cfg(feature = "k2v")]
pub fn k2v_client(&self, bucket: &str) -> K2vClient { pub fn k2v_client(&self, bucket: &str) -> K2vClient {
let config = k2v_client::K2vClientConfig { let config = k2v_client::K2vClientConfig {
+16 -16
View File
@@ -95,7 +95,7 @@ impl K2vClient {
}) })
} }
/// Perform a ReadItem request, reading the value(s) stored for a single pk+sk. /// Perform a `ReadItem` request, reading the value(s) stored for a single pk+sk.
pub async fn read_item( pub async fn read_item(
&self, &self,
partition_key: &str, partition_key: &str,
@@ -134,7 +134,7 @@ impl K2vClient {
} }
} }
/// Perform a PollItem request, waiting for the value(s) stored for a single pk+sk to be /// Perform a `PollItem` request, waiting for the value(s) stored for a single pk+sk to be
/// updated. /// updated.
pub async fn poll_item( pub async fn poll_item(
&self, &self,
@@ -190,7 +190,7 @@ impl K2vClient {
} }
} }
/// Perform a PollRange request, waiting for any change in a given range of keys /// Perform a `PollRange` request, waiting for any change in a given range of keys
/// to occur /// to occur
pub async fn poll_range( pub async fn poll_range(
&self, &self,
@@ -239,7 +239,7 @@ impl K2vClient {
})) }))
} }
/// Perform an InsertItem request, inserting a value for a single pk+sk. /// Perform an `InsertItem` request, inserting a value for a single pk+sk.
pub async fn insert_item( pub async fn insert_item(
&self, &self,
partition_key: &str, partition_key: &str,
@@ -258,7 +258,7 @@ impl K2vClient {
Ok(()) Ok(())
} }
/// Perform a DeleteItem request, deleting the value(s) stored for a single pk+sk. /// Perform a `DeleteItem` request, deleting the value(s) stored for a single pk+sk.
pub async fn delete_item( pub async fn delete_item(
&self, &self,
partition_key: &str, partition_key: &str,
@@ -274,7 +274,7 @@ impl K2vClient {
Ok(()) Ok(())
} }
/// Perform a ReadIndex request, listing partition key which have at least one associated /// Perform a `ReadIndex` request, listing partition key which have at least one associated
/// sort key, and which matches the filter. /// sort key, and which matches the filter.
pub async fn read_index( pub async fn read_index(
&self, &self,
@@ -300,7 +300,7 @@ impl K2vClient {
}) })
} }
/// Perform an InsertBatch request, inserting multiple values at once. Note: this operation is /// Perform an `InsertBatch` request, inserting multiple values at once. Note: this operation is
/// *not* atomic: it is possible for some sub-operations to fails and others to success. In /// *not* atomic: it is possible for some sub-operations to fails and others to success. In
/// that case, failure is reported. /// that case, failure is reported.
pub async fn insert_batch(&self, operations: &[BatchInsertOp<'_>]) -> Result<(), Error> { pub async fn insert_batch(&self, operations: &[BatchInsertOp<'_>]) -> Result<(), Error> {
@@ -312,7 +312,7 @@ impl K2vClient {
Ok(()) Ok(())
} }
/// Perform a ReadBatch request, reading multiple values or range of values at once. /// Perform a `ReadBatch` request, reading multiple values or range of values at once.
pub async fn read_batch( pub async fn read_batch(
&self, &self,
operations: &[BatchReadOp<'_>], operations: &[BatchReadOp<'_>],
@@ -346,7 +346,7 @@ impl K2vClient {
.collect()) .collect())
} }
/// Perform a DeleteBatch request, deleting multiple values or range of values at once, without /// Perform a `DeleteBatch` request, deleting multiple values or range of values at once, without
/// providing causality information. /// providing causality information.
pub async fn delete_batch(&self, operations: &[BatchDeleteOp<'_>]) -> Result<Vec<u64>, Error> { pub async fn delete_batch(&self, operations: &[BatchDeleteOp<'_>]) -> Result<Vec<u64>, Error> {
let url = self.build_url(None, &[("delete", "")]); let url = self.build_url(None, &[("delete", "")]);
@@ -588,7 +588,7 @@ impl Serialize for K2vValue {
} }
} }
/// A set of K2vValue and associated causality information. /// A set of `K2vValue` and associated causality information.
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct CausalValue { pub struct CausalValue {
pub causality: CausalityToken, pub causality: CausalityToken,
@@ -621,12 +621,12 @@ pub struct PollRangeFilter<'a> {
pub prefix: Option<&'a str>, pub prefix: Option<&'a str>,
} }
/// Response to a poll_range query /// Response to a `poll_range` query
#[derive(Debug, Default, Clone, Serialize)] #[derive(Debug, Default, Clone, Serialize)]
pub struct PollRangeResult { pub struct PollRangeResult {
/// List of items that have changed since last PollRange call. /// List of items that have changed since last `PollRange` call.
pub items: BTreeMap<String, CausalValue>, pub items: BTreeMap<String, CausalValue>,
/// opaque string representing items already seen for future PollRange calls. /// opaque string representing items already seen for future `PollRange` calls.
pub seen_marker: String, pub seen_marker: String,
} }
@@ -696,7 +696,7 @@ pub struct PartitionInfo {
pub bytes: u64, pub bytes: u64,
} }
/// Single sub-operation of an InsertBatch. /// Single sub-operation of an `InsertBatch`.
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct BatchInsertOp<'a> { pub struct BatchInsertOp<'a> {
#[serde(rename = "pk")] #[serde(rename = "pk")]
@@ -709,7 +709,7 @@ pub struct BatchInsertOp<'a> {
pub value: K2vValue, pub value: K2vValue,
} }
/// Single sub-operation of a ReadBatch. /// Single sub-operation of a `ReadBatch`.
#[derive(Debug, Default, Clone, Deserialize, Serialize)] #[derive(Debug, Default, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct BatchReadOp<'a> { pub struct BatchReadOp<'a> {
@@ -743,7 +743,7 @@ struct BatchReadItem {
v: Vec<K2vValue>, v: Vec<K2vValue>,
} }
/// Single sub-operation of a DeleteBatch /// Single sub-operation of a `DeleteBatch`
#[derive(Debug, Clone, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct BatchDeleteOp<'a> { pub struct BatchDeleteOp<'a> {
+1 -1
View File
@@ -73,7 +73,7 @@ impl Crdt for AdminApiTokenScope {
impl AdminApiToken { impl AdminApiToken {
/// Create a new admin API token. /// Create a new admin API token.
/// Returns the AdminApiToken object, which contains the hashed bearer token, /// Returns the `AdminApiToken` object, which contains the hashed bearer token,
/// as well as the plaintext bearer token. /// as well as the plaintext bearer token.
pub fn new(name: &str) -> (Self, String) { pub fn new(name: &str) -> (Self, String) {
use argon2::{ use argon2::{
+3 -3
View File
@@ -35,7 +35,7 @@ mod v08 {
/// Map of aliases that are or have been given to this bucket /// Map of aliases that are or have been given to this bucket
/// in the global namespace /// in the global namespace
/// (not authoritative: this is just used as an indication to /// (not authoritative: this is just used as an indication to
/// map back to aliases when doing ListBuckets) /// map back to aliases when doing `ListBuckets`)
pub aliases: crdt::LwwMap<String, bool>, pub aliases: crdt::LwwMap<String, bool>,
/// Map of aliases that are or have been given to this bucket /// Map of aliases that are or have been given to this bucket
/// in namespaces local to keys /// in namespaces local to keys
@@ -148,7 +148,7 @@ mod v2 {
/// Map of aliases that are or have been given to this bucket /// Map of aliases that are or have been given to this bucket
/// in the global namespace /// in the global namespace
/// (not authoritative: this is just used as an indication to /// (not authoritative: this is just used as an indication to
/// map back to aliases when doing ListBuckets) /// map back to aliases when doing `ListBuckets`)
pub aliases: crdt::LwwMap<String, bool>, pub aliases: crdt::LwwMap<String, bool>,
/// Map of aliases that are or have been given to this bucket /// Map of aliases that are or have been given to this bucket
/// in namespaces local to keys /// in namespaces local to keys
@@ -241,7 +241,7 @@ impl AutoCrdt for BucketQuotas {
} }
impl BucketParams { impl BucketParams {
/// Create an empty BucketParams with no authorized keys and no website access /// Create an empty `BucketParams` with no authorized keys and no website access
fn new() -> Self { fn new() -> Self {
BucketParams { BucketParams {
creation_date: now_msec(), creation_date: now_msec(),
+2 -2
View File
@@ -79,7 +79,7 @@ impl<'a> BucketHelper<'a> {
/// aliases directly using the data provided in the `api_key` parameter. /// aliases directly using the data provided in the `api_key` parameter.
/// As a consequence, it does not provide read-after-write guarantees. /// As a consequence, it does not provide read-after-write guarantees.
/// ///
/// In case no such bucket is found, this function returns a NoSuchBucket error. /// In case no such bucket is found, this function returns a `NoSuchBucket` error.
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub fn resolve_bucket_fast( pub fn resolve_bucket_fast(
&self, &self,
@@ -147,7 +147,7 @@ impl<'a> BucketHelper<'a> {
/// ///
/// - this function does quorum reads to ensure consistency. /// - this function does quorum reads to ensure consistency.
/// - this function fetches the Key entry from the key table to ensure up-to-date data /// - this function fetches the Key entry from the key table to ensure up-to-date data
/// - this function returns None if the bucket is not found, instead of HelperError::NoSuchBucket /// - this function returns None if the bucket is not found, instead of `HelperError::NoSuchBucket`
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub async fn resolve_bucket( pub async fn resolve_bucket(
&self, &self,
+4 -4
View File
@@ -17,13 +17,13 @@ use crate::helper::key::KeyHelper;
use crate::key_table::*; use crate::key_table::*;
use crate::permission::BucketKeyPerm; use crate::permission::BucketKeyPerm;
/// A LockedHelper is the mandatory struct to hold when doing operations /// A `LockedHelper` is the mandatory struct to hold when doing operations
/// that modify access keys or bucket aliases. This structure takes /// that modify access keys or bucket aliases. This structure takes
/// a lock to a unit value that is in the globally-shared Garage struct. /// a lock to a unit value that is in the globally-shared Garage struct.
/// ///
/// This avoid several concurrent requests to modify the list of buckets /// This avoid several concurrent requests to modify the list of buckets
/// and aliases at the same time, ending up in inconsistent states. /// and aliases at the same time, ending up in inconsistent states.
/// This DOES NOT FIX THE FUNDAMENTAL ISSUE as CreateBucket requests handled /// This DOES NOT FIX THE FUNDAMENTAL ISSUE as `CreateBucket` requests handled
/// by different API nodes can still break the cluster, but it is a first /// by different API nodes can still break the cluster, but it is a first
/// fix that allows consistency to be maintained if all such requests are /// fix that allows consistency to be maintained if all such requests are
/// directed to a single node, which is doable for many deployments. /// directed to a single node, which is doable for many deployments.
@@ -167,7 +167,7 @@ impl<'a> LockedHelper<'a> {
} }
/// Ensures a bucket does not have a certain global alias. /// Ensures a bucket does not have a certain global alias.
/// Contrarily to unset_global_bucket_alias, this does not /// Contrarily to `unset_global_bucket_alias`, this does not
/// fail on any condition other than: /// fail on any condition other than:
/// - bucket cannot be found (its fine if it is in deleted state) /// - bucket cannot be found (its fine if it is in deleted state)
/// - alias cannot be found (its fine if it points to nothing or /// - alias cannot be found (its fine if it points to nothing or
@@ -335,7 +335,7 @@ impl<'a> LockedHelper<'a> {
} }
/// Ensures a bucket does not have a certain local alias. /// Ensures a bucket does not have a certain local alias.
/// Contrarily to unset_local_bucket_alias, this does not /// Contrarily to `unset_local_bucket_alias`, this does not
/// fail on any condition other than: /// fail on any condition other than:
/// - bucket cannot be found (its fine if it is in deleted state) /// - bucket cannot be found (its fine if it is in deleted state)
/// - key cannot be found (its fine if alias in key points to nothing /// - key cannot be found (its fine if alias in key points to nothing
+2 -2
View File
@@ -1,9 +1,9 @@
//! Implements a CausalContext, which is a set of timestamps for each //! Implements a `CausalContext`, which is a set of timestamps for each
//! node -- a vector clock --, indicating that the versions with //! node -- a vector clock --, indicating that the versions with
//! timestamps <= these numbers have been seen and can be //! timestamps <= these numbers have been seen and can be
//! overwritten by a subsequent write. //! overwritten by a subsequent write.
//! //!
//! The textual representation of a CausalContext, which we call a //! The textual representation of a `CausalContext`, which we call a
//! "causality token", is used in the API and must be sent along with //! "causality token", is used in the API and must be sent along with
//! each write or delete operation to indicate the previously seen //! each write or delete operation to indicate the previously seen
//! versions that we want to overwrite or delete. //! versions that we want to overwrite or delete.
+2 -2
View File
@@ -56,7 +56,7 @@ mod v08 {
pub use v08::*; pub use v08::*;
impl K2VItem { impl K2VItem {
/// Creates a new K2VItem when no previous entry existed in the db /// Creates a new `K2VItem` when no previous entry existed in the db
pub fn new(bucket_id: Uuid, partition_key: String, sort_key: String) -> Self { pub fn new(bucket_id: Uuid, partition_key: String, sort_key: String) -> Self {
Self { Self {
partition: K2VItemPartition { partition: K2VItemPartition {
@@ -67,7 +67,7 @@ impl K2VItem {
items: BTreeMap::new(), items: BTreeMap::new(),
} }
} }
/// Updates a K2VItem with a new value or a deletion event /// Updates a `K2VItem` with a new value or a deletion event
pub fn update( pub fn update(
&mut self, &mut self,
this_node: Uuid, this_node: Uuid,
+1 -1
View File
@@ -1,4 +1,4 @@
//! Implements a RangeSeenMarker, a data type used in the PollRange API //! Implements a `RangeSeenMarker`, a data type used in the `PollRange` API
//! to indicate which items in the range have already been seen //! to indicate which items in the range have already been seen
//! and which have not been seen yet. //! and which have not been seen yet.
//! //!
+2 -2
View File
@@ -27,7 +27,7 @@ mod v08 {
/// Configuration for a key /// Configuration for a key
#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)] #[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
pub struct KeyParams { pub struct KeyParams {
/// The secret_key associated (immutable) /// The `secret_key` associated (immutable)
pub secret_key: String, pub secret_key: String,
/// Name for the key /// Name for the key
@@ -73,7 +73,7 @@ mod v2 {
/// Key's creation date, if known (older versions of Garage didn't keep track /// Key's creation date, if known (older versions of Garage didn't keep track
/// of this information) /// of this information)
pub created: Option<u64>, pub created: Option<u64>,
/// The secret_key associated (immutable) /// The `secret_key` associated (immutable)
pub secret_key: String, pub secret_key: String,
/// Name for the key /// Name for the key
+4 -4
View File
@@ -31,12 +31,12 @@ mod v09 {
/// The timestamp at which the multipart upload was created /// The timestamp at which the multipart upload was created
pub timestamp: u64, pub timestamp: u64,
/// Is this multipart upload deleted /// Is this multipart upload deleted
/// The MultipartUpload is marked as deleted as soon as the /// The `MultipartUpload` is marked as deleted as soon as the
/// multipart upload is either completed or aborted /// multipart upload is either completed or aborted
pub deleted: crdt::Bool, pub deleted: crdt::Bool,
/// List of uploaded parts, key = (part number, timestamp) /// List of uploaded parts, key = (part number, timestamp)
/// In case of retries, all versions for each part are kept /// In case of retries, all versions for each part are kept
/// Everything is cleaned up only once the MultipartUpload is marked deleted /// Everything is cleaned up only once the `MultipartUpload` is marked deleted
pub parts: crdt::Map<MpuPartKey, MpuPart>, pub parts: crdt::Map<MpuPartKey, MpuPart>,
// Back link to bucket+key so that we can find the object this mpu // Back link to bucket+key so that we can find the object this mpu
@@ -58,9 +58,9 @@ mod v09 {
/// The version of an uploaded part /// The version of an uploaded part
#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)] #[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
pub struct MpuPart { pub struct MpuPart {
/// Links to a Version in VersionTable /// Links to a Version in `VersionTable`
pub version: Uuid, pub version: Uuid,
/// ETag of the content of this part (known only once done uploading) /// `ETag` of the content of this part (known only once done uploading)
pub etag: Option<String>, pub etag: Option<String>,
/// Checksum requested by x-amz-checksum-algorithm /// Checksum requested by x-amz-checksum-algorithm
#[serde(default)] #[serde(default)]
+9 -9
View File
@@ -249,7 +249,7 @@ mod v010 {
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Serialize, Deserialize)] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Serialize, Deserialize)]
pub enum ObjectVersionEncryption { pub enum ObjectVersionEncryption {
SseC { SseC {
/// Encrypted serialized ObjectVersionInner struct. /// Encrypted serialized `ObjectVersionInner` struct.
/// This is never compressed, just encrypted using AES256-GCM. /// This is never compressed, just encrypted using AES256-GCM.
#[serde(with = "serde_bytes")] #[serde(with = "serde_bytes")]
inner: Vec<u8>, inner: Vec<u8>,
@@ -460,7 +460,7 @@ mod v2 {
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Serialize, Deserialize)] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Serialize, Deserialize)]
pub enum ObjectVersionEncryption { pub enum ObjectVersionEncryption {
SseC { SseC {
/// Encrypted serialized ObjectVersionInner struct. /// Encrypted serialized `ObjectVersionInner` struct.
/// This is never compressed, just encrypted using AES256-GCM. /// This is never compressed, just encrypted using AES256-GCM.
#[serde(with = "serde_bytes")] #[serde(with = "serde_bytes")]
inner: Vec<u8>, inner: Vec<u8>,
@@ -480,7 +480,7 @@ mod v2 {
} }
/// Vector of headers, as tuples of the format (header name, header value) /// Vector of headers, as tuples of the format (header name, header value)
/// Note: checksum can be Some(_) with checksum_type = None for objects that /// Note: checksum can be Some(_) with `checksum_type` = None for objects that
/// have been migrated from Garage version before v2.0, as the distinction between /// have been migrated from Garage version before v2.0, as the distinction between
/// full-object and composite checksums was not implemented yet. /// full-object and composite checksums was not implemented yet.
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Serialize, Deserialize)] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Serialize, Deserialize)]
@@ -665,9 +665,9 @@ impl ObjectVersion {
/// Is the object version currently being uploaded /// Is the object version currently being uploaded
/// ///
/// matches only multipart uploads if check_multipart is Some(true) /// matches only multipart uploads if `check_multipart` is Some(true)
/// matches only non-multipart uploads if check_multipart is Some(false) /// matches only non-multipart uploads if `check_multipart` is Some(false)
/// matches both if check_multipart is None /// matches both if `check_multipart` is None
pub fn is_uploading(&self, check_multipart: Option<bool>) -> bool { pub fn is_uploading(&self, check_multipart: Option<bool>) -> bool {
match &self.state { match &self.state {
ObjectVersionState::Uploading { multipart, .. } => { ObjectVersionState::Uploading { multipart, .. } => {
@@ -763,9 +763,9 @@ pub enum ObjectFilter {
IsData, IsData,
/// Is the object version currently being uploaded /// Is the object version currently being uploaded
/// ///
/// matches only multipart uploads if check_multipart is Some(true) /// matches only multipart uploads if `check_multipart` is Some(true)
/// matches only non-multipart uploads if check_multipart is Some(false) /// matches only non-multipart uploads if `check_multipart` is Some(false)
/// matches both if check_multipart is None /// matches both if `check_multipart` is None
IsUploading { check_multipart: Option<bool> }, IsUploading { check_multipart: Option<bool> },
} }
+1 -1
View File
@@ -20,7 +20,7 @@ static SNAPSHOT_MUTEX: Mutex<()> = Mutex::new(());
// ================ snapshotting logic ===================== // ================ snapshotting logic =====================
/// Run snapshot_metadata in a blocking thread and async await on it /// Run `snapshot_metadata` in a blocking thread and async await on it
pub async fn async_snapshot_metadata(garage: &Arc<Garage>) -> Result<(), Error> { pub async fn async_snapshot_metadata(garage: &Arc<Garage>) -> Result<(), Error> {
let garage = garage.clone(); let garage = garage.clone();
let worker = tokio::task::spawn_blocking(move || snapshot_metadata(&garage)); let worker = tokio::task::spawn_blocking(move || snapshot_metadata(&garage));
+5 -5
View File
@@ -17,7 +17,7 @@ pub struct BytesBuf {
} }
impl BytesBuf { impl BytesBuf {
/// Creates a new empty BytesBuf /// Creates a new empty `BytesBuf`
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
buf: VecDeque::new(), buf: VecDeque::new(),
@@ -25,13 +25,13 @@ impl BytesBuf {
} }
} }
/// Returns the number of bytes stored in the BytesBuf /// Returns the number of bytes stored in the `BytesBuf`
#[inline] #[inline]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.buf_len self.buf_len
} }
/// Returns true iff the BytesBuf contains zero bytes /// Returns true iff the `BytesBuf` contains zero bytes
#[inline] #[inline]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.buf_len == 0 self.buf_len == 0
@@ -63,7 +63,7 @@ impl BytesBuf {
} }
} }
/// Takes at most max_len bytes from the left of the buffer /// Takes at most `max_len` bytes from the left of the buffer
pub fn take_max(&mut self, max_len: usize) -> Bytes { pub fn take_max(&mut self, max_len: usize) -> Bytes {
if self.buf_len <= max_len { if self.buf_len <= max_len {
self.take_all() self.take_all()
@@ -73,7 +73,7 @@ impl BytesBuf {
} }
/// Take exactly len bytes from the left of the buffer, returns None if /// Take exactly len bytes from the left of the buffer, returns None if
/// the BytesBuf doesn't contain enough data /// the `BytesBuf` doesn't contain enough data
pub fn take_exact(&mut self, len: usize) -> Option<Bytes> { pub fn take_exact(&mut self, len: usize) -> Option<Bytes> {
if self.buf_len < len { if self.buf_len < len {
None None
+5 -5
View File
@@ -101,9 +101,9 @@ pub trait Message: Serialize + for<'de> Deserialize<'de> + Send + Sync + 'static
// ---- // ----
/// The `Req<M>` is a helper object used to create requests and attach them /// The `Req<M>` is a helper object used to create requests and attach them
/// a stream of data. If the stream is a fixed Bytes and not a ByteStream, /// a stream of data. If the stream is a fixed Bytes and not a `ByteStream`,
/// `Req<M>` is cheaply cloneable to allow the request to be sent to different /// `Req<M>` is cheaply cloneable to allow the request to be sent to different
/// peers (Clone will panic if the stream is a ByteStream). /// peers (Clone will panic if the stream is a `ByteStream`).
pub struct Req<M: Message> { pub struct Req<M: Message> {
pub(crate) msg: Arc<M>, pub(crate) msg: Arc<M>,
pub(crate) msg_ser: Option<Bytes>, pub(crate) msg_ser: Option<Bytes>,
@@ -382,7 +382,7 @@ impl AttachedStream {
// ---- ---- // ---- ----
/// Encoding for requests into a ByteStream: /// Encoding for requests into a `ByteStream`:
/// - priority: u8 /// - priority: u8
/// - path length: u8 /// - path length: u8
/// - path: [u8; path length] /// - path: [u8; path length]
@@ -457,7 +457,7 @@ impl ReqEnc {
} }
} }
/// Encoding for responses into a ByteStream: /// Encoding for responses into a `ByteStream`:
/// ///
/// IF SUCCESS: /// IF SUCCESS:
/// - 0: u8 /// - 0: u8
@@ -468,7 +468,7 @@ impl ReqEnc {
/// IF ERROR: /// IF ERROR:
/// - message length + 1: u8 /// - message length + 1: u8
/// - error code: u8 /// - error code: u8
/// - message: [u8; message_length] /// - message: [u8; `message_length`]
pub(crate) struct RespEnc { pub(crate) struct RespEnc {
msg: Bytes, msg: Bytes,
stream: Option<ByteStream>, stream: Option<ByteStream>,
+8 -8
View File
@@ -34,12 +34,12 @@ pub type NetworkKey = sodiumoxide::crypto::auth::Key;
/// composed of 8 bytes for Netapp version and 8 bytes for client version /// composed of 8 bytes for Netapp version and 8 bytes for client version
pub(crate) type VersionTag = [u8; 16]; pub(crate) type VersionTag = [u8; 16];
/// Value of garage_net version used in the version tag /// Value of `garage_net` version used in the version tag
/// We are no longer using prefix `netapp` as garage_net is forked from the netapp crate. /// We are no longer using prefix `netapp` as `garage_net` is forked from the netapp crate.
/// Since Garage v1.0, we have replaced the prefix by `grgnet` (shorthand for garage_net). /// Since Garage v1.0, we have replaced the prefix by `grgnet` (shorthand for `garage_net`).
pub(crate) const NETAPP_VERSION_TAG: u64 = 0x6772676e65740010; // grgnet 0x0010 (1.0) pub(crate) const NETAPP_VERSION_TAG: u64 = 0x6772676e65740010; // grgnet 0x0010 (1.0)
/// HelloMessage is sent by the client on a Netapp connection to indicate /// `HelloMessage` is sent by the client on a Netapp connection to indicate
/// that they are also a server and ready to receive incoming connections /// that they are also a server and ready to receive incoming connections
/// at the specified address and port. If the client doesn't know their /// at the specified address and port. If the client doesn't know their
/// public address, they don't need to specify it and we look at the /// public address, they don't need to specify it and we look at the
@@ -57,9 +57,9 @@ impl Message for HelloMessage {
type OnConnectHandler = Box<dyn Fn(NodeID, SocketAddr, bool) + Send + Sync>; type OnConnectHandler = Box<dyn Fn(NodeID, SocketAddr, bool) + Send + Sync>;
type OnDisconnectHandler = Box<dyn Fn(NodeID, bool) + Send + Sync>; type OnDisconnectHandler = Box<dyn Fn(NodeID, bool) + Send + Sync>;
/// NetApp is the main class that handles incoming and outgoing connections. /// `NetApp` is the main class that handles incoming and outgoing connections.
/// ///
/// NetApp can be used in a stand-alone fashion or together with a peering strategy. /// `NetApp` can be used in a stand-alone fashion or together with a peering strategy.
/// If using it alone, you will want to set `on_connect` and `on_disconnect` events /// If using it alone, you will want to set `on_connect` and `on_disconnect` events
/// in order to manage information about the current peer list. /// in order to manage information about the current peer list.
pub struct NetApp { pub struct NetApp {
@@ -91,7 +91,7 @@ struct ListenParams {
} }
impl NetApp { impl NetApp {
/// Creates a new instance of NetApp, which can serve either as a full p2p node, /// Creates a new instance of `NetApp`, which can serve either as a full p2p node,
/// or just as a passive client. To upgrade to a full p2p node, spawn a listener /// or just as a passive client. To upgrade to a full p2p node, spawn a listener
/// using `.listen()` /// using `.listen()`
/// ///
@@ -186,7 +186,7 @@ impl NetApp {
/// Main listening process for our app. This future runs during the whole /// Main listening process for our app. This future runs during the whole
/// run time of our application. /// run time of our application.
/// If this is not called, the NetApp instance remains a passive client. /// If this is not called, the `NetApp` instance remains a passive client.
pub async fn listen( pub async fn listen(
self: Arc<Self>, self: Arc<Self>,
listen_addr: SocketAddr, listen_addr: SocketAddr,
+1 -1
View File
@@ -119,7 +119,7 @@ impl PeerInfo {
} }
} }
/// PeerConnState: possible states for our tentative connections to given peer /// `PeerConnState`: possible states for our tentative connections to given peer
/// This structure is only interested in recording connection info for outgoing /// This structure is only interested in recording connection info for outgoing
/// TCP connections /// TCP connections
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
+2 -2
View File
@@ -42,8 +42,8 @@ impl Drop for Sender {
} }
} }
/// The RecvLoop trait, which is implemented both by the client and the server /// The `RecvLoop` trait, which is implemented both by the client and the server
/// connection objects (ServerConn and ClientConn) adds a method `.recv_loop()` /// connection objects (`ServerConn` and `ClientConn`) adds a method `.recv_loop()`
/// and a prototype of a handler for received messages `.recv_handler()` that /// and a prototype of a handler for received messages `.recv_handler()` that
/// must be filled by implementors. `.recv_loop()` receives messages in a loop /// must be filled by implementors. `.recv_loop()` receives messages in a loop
/// according to the protocol defined above: chunks of message in progress of being /// according to the protocol defined above: chunks of message in progress of being
+2 -2
View File
@@ -264,8 +264,8 @@ impl DataFrame {
} }
} }
/// The SendLoop trait, which is implemented both by the client and the server /// The `SendLoop` trait, which is implemented both by the client and the server
/// connection objects (ServerConna and ClientConn) adds a method `.send_loop()` /// connection objects (`ServerConna` and `ClientConn`) adds a method `.send_loop()`
/// that takes a channel of messages to send and an asynchronous writer, /// that takes a channel of messages to send and an asynchronous writer,
/// and sends messages from the channel to the async writer, putting them in a queue /// and sends messages from the channel to the async writer, putting them in a queue
/// before being sent and doing the round-robin sending strategy. /// before being sent and doing the round-robin sending strategy.
+5 -5
View File
@@ -14,18 +14,18 @@ use crate::bytes_buf::BytesBuf;
/// When sent through Netapp, the Vec may be split in smaller chunk in such a way /// When sent through Netapp, the Vec may be split in smaller chunk in such a way
/// consecutive Vec may get merged, but Vec and error code may not be reordered /// consecutive Vec may get merged, but Vec and error code may not be reordered
/// ///
/// Items sent in the ByteStream may be errors of type `std::io::Error`. /// Items sent in the `ByteStream` may be errors of type `std::io::Error`.
/// An error indicates the end of the ByteStream: a reader should no longer read /// An error indicates the end of the `ByteStream`: a reader should no longer read
/// after receiving an error, and a writer should stop writing after sending an error. /// after receiving an error, and a writer should stop writing after sending an error.
pub type ByteStream = Pin<Box<dyn Stream<Item = Packet> + Send + Sync>>; pub type ByteStream = Pin<Box<dyn Stream<Item = Packet> + Send + Sync>>;
/// A packet sent in a ByteStream, which may contain either /// A packet sent in a `ByteStream`, which may contain either
/// a Bytes object or an error /// a Bytes object or an error
pub type Packet = Result<Bytes, std::io::Error>; pub type Packet = Result<Bytes, std::io::Error>;
// ---- // ----
/// A helper struct to read defined lengths of data from a BytesStream /// A helper struct to read defined lengths of data from a `BytesStream`
pub struct ByteStreamReader { pub struct ByteStreamReader {
stream: ByteStream, stream: ByteStream,
buf: BytesBuf, buf: BytesBuf,
@@ -201,7 +201,7 @@ pub fn stream_asyncread(stream: ByteStream) -> impl AsyncRead + Send + Sync + 's
tokio_util::io::StreamReader::new(stream) tokio_util::io::StreamReader::new(stream)
} }
/// Reads all of the content of a `ByteStream` into a BytesBuf /// Reads all of the content of a `ByteStream` into a `BytesBuf`
/// that contains everything /// that contains everything
pub async fn read_stream_to_end(mut stream: ByteStream) -> Result<BytesBuf, std::io::Error> { pub async fn read_stream_to_end(mut stream: ByteStream) -> Result<BytesBuf, std::io::Error> {
let mut buf = BytesBuf::new(); let mut buf = BytesBuf::new();
+2 -2
View File
@@ -7,7 +7,7 @@ use tokio::sync::watch;
use crate::netapp::*; use crate::netapp::*;
/// Utility function: encodes any serializable value in MessagePack binary format /// Utility function: encodes any serializable value in `MessagePack` binary format
/// using the RMP library. /// using the RMP library.
/// ///
/// Field names and variant names are included in the serialization. /// Field names and variant names are included in the serialization.
@@ -80,7 +80,7 @@ pub fn parse_and_resolve_peer_addr(peer: &str) -> Option<(NodeID, Vec<SocketAddr
Some((pubkey, hosts)) Some((pubkey, hosts))
} }
/// async version of parse_and_resolve_peer_addr /// async version of `parse_and_resolve_peer_addr`
pub async fn parse_and_resolve_peer_addr_async(peer: &str) -> Option<(NodeID, Vec<SocketAddr>)> { pub async fn parse_and_resolve_peer_addr_async(peer: &str) -> Option<(NodeID, Vec<SocketAddr>)> {
let delim = peer.find('@')?; let delim = peer.find('@')?;
let (key, host) = peer.split_at(delim); let (key, host) = peer.split_at(delim);
+6 -6
View File
@@ -42,7 +42,7 @@ impl Edge for WeightedEdge {}
/// Struct for the graph structure. We do encapsulation here to be able to both /// Struct for the graph structure. We do encapsulation here to be able to both
/// provide user friendly Vertex enum to address vertices, and to use internally usize /// provide user friendly Vertex enum to address vertices, and to use internally usize
/// indices and Vec instead of HashMap in the graph algorithm to optimize execution speed. /// indices and Vec instead of `HashMap` in the graph algorithm to optimize execution speed.
pub struct Graph<E: Edge> { pub struct Graph<E: Edge> {
vertex_to_id: HashMap<Vertex, usize>, vertex_to_id: HashMap<Vertex, usize>,
id_to_vertex: Vec<Vertex>, id_to_vertex: Vec<Vertex>,
@@ -253,7 +253,7 @@ impl Graph<FlowEdge> {
/// This function takes a flow, and a cost function on the edges, and tries to find an /// This function takes a flow, and a cost function on the edges, and tries to find an
/// equivalent flow with a better cost, by finding improving overflow cycles. It uses /// equivalent flow with a better cost, by finding improving overflow cycles. It uses
/// as subroutine the Bellman Ford algorithm run up to path_length. /// as subroutine the Bellman Ford algorithm run up to `path_length`.
/// We assume that the cost of edge (u,v) is the opposite of the cost of (v,u), and /// We assume that the cost of edge (u,v) is the opposite of the cost of (v,u), and
/// only one needs to be present in the cost function. /// only one needs to be present in the cost function.
pub fn optimize_flow_with_cost( pub fn optimize_flow_with_cost(
@@ -290,7 +290,7 @@ impl Graph<FlowEdge> {
Ok(()) Ok(())
} }
/// Construct the weighted graph G_f from the flow and the cost function /// Construct the weighted graph `G_f` from the flow and the cost function
fn build_cost_graph(&self, cost: &CostFunction) -> Result<Graph<WeightedEdge>, String> { fn build_cost_graph(&self, cost: &CostFunction) -> Result<Graph<WeightedEdge>, String> {
let mut g = Graph::<WeightedEdge>::new(&self.id_to_vertex); let mut g = Graph::<WeightedEdge>::new(&self.id_to_vertex);
let nb_vertices = self.id_to_vertex.len(); let nb_vertices = self.id_to_vertex.len();
@@ -323,11 +323,11 @@ impl Graph<WeightedEdge> {
Ok(()) Ok(())
} }
/// This function lists the negative cycles it manages to find after path_length /// This function lists the negative cycles it manages to find after `path_length`
/// iterations of the main loop of the Bellman-Ford algorithm. For the classical /// iterations of the main loop of the Bellman-Ford algorithm. For the classical
/// algorithm, path_length needs to be equal to the number of vertices. However, /// algorithm, `path_length` needs to be equal to the number of vertices. However,
/// for particular graph structures like in our case, the algorithm is still correct /// for particular graph structures like in our case, the algorithm is still correct
/// when path_length is the length of the longest possible simple path. /// when `path_length` is the length of the longest possible simple path.
/// See the formal description of the algorithm for more details. /// See the formal description of the algorithm for more details.
fn list_negative_cycles(&self, path_length: usize) -> Vec<Vec<Vertex>> { fn list_negative_cycles(&self, path_length: usize) -> Vec<Vec<Vertex>> {
let nb_vertices = self.graph.len(); let nb_vertices = self.graph.len();
+1 -1
View File
@@ -162,7 +162,7 @@ impl LayoutHelper {
} }
/// Returns the latest layout version for which it is safe to read data from, /// Returns the latest layout version for which it is safe to read data from,
/// i.e. the version whose version number is sync_map_min /// i.e. the version whose version number is `sync_map_min`
pub fn read_version(&self) -> Result<&LayoutVersion, Error> { pub fn read_version(&self) -> Result<&LayoutVersion, Error> {
let sync_min = self.sync_map_min; let sync_min = self.sync_map_min;
let versions = self.versions()?; let versions = self.versions()?;
+9 -9
View File
@@ -23,7 +23,7 @@ pub use version::*;
/// A partition id, which is stored on 16 bits /// A partition id, which is stored on 16 bits
/// i.e. we have up to 2**16 partitions. /// i.e. we have up to 2**16 partitions.
/// (in practice we have exactly 2**PARTITION_BITS partitions) /// (in practice we have exactly 2**`PARTITION_BITS` partitions)
pub type Partition = u16; pub type Partition = u16;
// TODO: make this constant parametrizable in the config file // TODO: make this constant parametrizable in the config file
@@ -114,7 +114,7 @@ mod v09 {
/// to know to what extent does it change with the layout update. /// to know to what extent does it change with the layout update.
pub partition_size: u64, pub partition_size: u64,
/// Parameters used to compute the assignment currently given by /// Parameters used to compute the assignment currently given by
/// ring_assignment_data /// `ring_assignment_data`
pub parameters: LayoutParameters, pub parameters: LayoutParameters,
pub roles: LwwMap<Uuid, NodeRoleV>, pub roles: LwwMap<Uuid, NodeRoleV>,
@@ -229,7 +229,7 @@ mod v010 {
use std::collections::BTreeMap; use std::collections::BTreeMap;
pub use v09::{LayoutParameters, NodeRole, NodeRoleV, ZoneRedundancy}; pub use v09::{LayoutParameters, NodeRole, NodeRoleV, ZoneRedundancy};
/// Number of old (non-live) versions to keep, see LayoutHistory::old_versions /// Number of old (non-live) versions to keep, see `LayoutHistory::old_versions`
pub const OLD_VERSION_COUNT: usize = 5; pub const OLD_VERSION_COUNT: usize = 5;
/// The history of cluster layouts, with trackers to keep a record /// The history of cluster layouts, with trackers to keep a record
@@ -238,8 +238,8 @@ mod v010 {
pub struct LayoutHistory { pub struct LayoutHistory {
/// The versions currently in use in the cluster /// The versions currently in use in the cluster
pub versions: Vec<LayoutVersion>, pub versions: Vec<LayoutVersion>,
/// At most 5 of the previous versions, not used by the garage_table /// At most 5 of the previous versions, not used by the `garage_table`
/// module, but useful for the garage_block module to find data blocks /// module, but useful for the `garage_block` module to find data blocks
/// that have not yet been moved /// that have not yet been moved
pub old_versions: Vec<LayoutVersion>, pub old_versions: Vec<LayoutVersion>,
@@ -260,7 +260,7 @@ mod v010 {
/// Roles assigned to nodes in this version /// Roles assigned to nodes in this version
pub roles: LwwMap<Uuid, NodeRoleV>, pub roles: LwwMap<Uuid, NodeRoleV>,
/// Parameters used to compute the assignment currently given by /// Parameters used to compute the assignment currently given by
/// ring_assignment_data /// `ring_assignment_data`
pub parameters: LayoutParameters, pub parameters: LayoutParameters,
/// The number of replicas for each data partition /// The number of replicas for each data partition
@@ -269,17 +269,17 @@ mod v010 {
/// to know to what extent does it change with the layout update. /// to know to what extent does it change with the layout update.
pub partition_size: u64, pub partition_size: u64,
/// node_id_vec: a vector of node IDs with a role assigned /// `node_id_vec`: a vector of node IDs with a role assigned
/// in the system (this includes gateway nodes). /// in the system (this includes gateway nodes).
/// The order here is different than the vec stored by `roles`, because: /// The order here is different than the vec stored by `roles`, because:
/// 1. non-gateway nodes are first so that they have lower numbers /// 1. non-gateway nodes are first so that they have lower numbers
/// 2. nodes that don't have a role are excluded (but they need to /// 2. nodes that don't have a role are excluded (but they need to
/// stay in the CRDT as tombstones) /// stay in the CRDT as tombstones)
pub node_id_vec: Vec<Uuid>, pub node_id_vec: Vec<Uuid>,
/// number of non-gateway nodes, which are the first ids in node_id_vec /// number of non-gateway nodes, which are the first ids in `node_id_vec`
pub nongateway_node_count: usize, pub nongateway_node_count: usize,
/// The assignation of data partitions to nodes, the values /// The assignation of data partitions to nodes, the values
/// are indices in node_id_vec /// are indices in `node_id_vec`
#[serde(with = "serde_bytes")] #[serde(with = "serde_bytes")]
pub ring_assignment_data: Vec<CompactNodeType>, pub ring_assignment_data: Vec<CompactNodeType>,
} }
+7 -7
View File
@@ -164,7 +164,7 @@ impl LayoutVersion {
total_capacity total_capacity
} }
/// Returns the effective value of the zone_redundancy parameter /// Returns the effective value of the `zone_redundancy` parameter
pub(crate) fn effective_zone_redundancy(&self) -> usize { pub(crate) fn effective_zone_redundancy(&self) -> usize {
match self.parameters.zone_redundancy { match self.parameters.zone_redundancy {
ZoneRedundancy::AtLeast(v) => v, ZoneRedundancy::AtLeast(v) => v,
@@ -311,7 +311,7 @@ impl LayoutVersion {
/// the former assignment (if any) to minimize the amount of /// the former assignment (if any) to minimize the amount of
/// data to be moved. /// data to be moved.
/// Staged role changes must be merged with nodes roles before calling this function, /// Staged role changes must be merged with nodes roles before calling this function,
/// hence it must only be called from apply_staged_changes() and hence is not public. /// hence it must only be called from `apply_staged_changes()` and hence is not public.
fn calculate_partition_assignment(&mut self) -> Result<Message, Error> { fn calculate_partition_assignment(&mut self) -> Result<Message, Error> {
// We update the node ids, since the node role list might have changed with the // We update the node ids, since the node role list might have changed with the
// changes in the layout. We retrieve the old_assignment reframed with new ids // changes in the layout. We retrieve the old_assignment reframed with new ids
@@ -402,11 +402,11 @@ impl LayoutVersion {
Ok(msg) Ok(msg)
} }
/// The LwwMap of node roles might have changed. This function updates the node_id_vec /// The `LwwMap` of node roles might have changed. This function updates the `node_id_vec`
/// and returns the assignment given by ring, with the new indices of the nodes, and /// and returns the assignment given by ring, with the new indices of the nodes, and
/// None if the node is not present anymore. /// None if the node is not present anymore.
/// We work with the assumption that only this function and calculate_new_assignment /// We work with the assumption that only this function and `calculate_new_assignment`
/// do modify assignment_ring and node_id_vec. /// do modify `assignment_ring` and `node_id_vec`.
fn update_node_id_vec(&mut self) -> Result<Option<Vec<Vec<usize>>>, Error> { fn update_node_id_vec(&mut self) -> Result<Option<Vec<Vec<usize>>>, Error> {
// (1) We compute the new node list // (1) We compute the new node list
// Non gateway nodes should be coded on 8bits, hence they must be first in the list // Non gateway nodes should be coded on 8bits, hence they must be first in the list
@@ -488,7 +488,7 @@ impl LayoutVersion {
} }
/// This function generates ids for the zone of the nodes appearing in /// This function generates ids for the zone of the nodes appearing in
/// self.node_id_vec. /// `self.node_id_vec`.
pub(crate) fn generate_nongateway_zone_ids( pub(crate) fn generate_nongateway_zone_ids(
&self, &self,
) -> Result<(Vec<String>, HashMap<String, usize>), Error> { ) -> Result<(Vec<String>, HashMap<String, usize>), Error> {
@@ -560,7 +560,7 @@ impl LayoutVersion {
/// Generates the graph to compute the maximal flow corresponding to the optimal /// Generates the graph to compute the maximal flow corresponding to the optimal
/// partition assignment. /// partition assignment.
/// exclude_assoc is the set of (partition, node) association that we are forbidden /// `exclude_assoc` is the set of (partition, node) association that we are forbidden
/// to use (hence we do not add the corresponding edge to the graph). This parameter /// to use (hence we do not add the corresponding edge to the graph). This parameter
/// is used to compute a first flow that uses only edges appearing in the previous /// is used to compute a first flow that uses only edges appearing in the previous
/// assignment. This produces a solution that heuristically should be close to the /// assignment. This produces a solution that heuristically should be close to the
+1 -1
View File
@@ -1,6 +1,6 @@
use opentelemetry::{global, metrics::*}; use opentelemetry::{global, metrics::*};
/// TableMetrics reference all counter used for metrics /// `TableMetrics` reference all counter used for metrics
pub struct RpcMetrics { pub struct RpcMetrics {
pub(crate) rpc_counter: Counter<u64>, pub(crate) rpc_counter: Counter<u64>,
pub(crate) rpc_timeout_counter: Counter<u64>, pub(crate) rpc_timeout_counter: Counter<u64>,
+4 -4
View File
@@ -66,7 +66,7 @@ impl Clone for RequestStrategy<()> {
} }
impl RequestStrategy<()> { impl RequestStrategy<()> {
/// Create a RequestStrategy with default timeout and not interrupting when quorum reached /// Create a `RequestStrategy` with default timeout and not interrupting when quorum reached
pub fn with_priority(prio: RequestPriority) -> Self { pub fn with_priority(prio: RequestPriority) -> Self {
RequestStrategy { RequestStrategy {
rs_quorum: None, rs_quorum: None,
@@ -109,7 +109,7 @@ impl<T> RequestStrategy<T> {
self.rs_timeout = Timeout::Custom(timeout); self.rs_timeout = Timeout::Custom(timeout);
self self
} }
/// Extract drop_on_complete item /// Extract `drop_on_complete` item
fn extract_drop_on_complete(self) -> (RequestStrategy<()>, T) { fn extract_drop_on_complete(self) -> (RequestStrategy<()>, T) {
( (
RequestStrategy { RequestStrategy {
@@ -272,7 +272,7 @@ impl RpcHelper {
/// Make a RPC call to multiple servers, returning either a Vec of responses, /// Make a RPC call to multiple servers, returning either a Vec of responses,
/// or an error if quorum could not be reached due to too many errors /// or an error if quorum could not be reached due to too many errors
/// ///
/// If RequestStrategy has send_all_at_once set, then all requests will be /// If `RequestStrategy` has `send_all_at_once` set, then all requests will be
/// sent at once, and `try_call_many` will return as soon as a quorum of /// sent at once, and `try_call_many` will return as soon as a quorum of
/// responses is achieved, dropping and cancelling the remaining requests. /// responses is achieved, dropping and cancelling the remaining requests.
/// ///
@@ -413,7 +413,7 @@ impl RpcHelper {
/// Make a RPC call to multiple servers, returning either a Vec of responses, /// Make a RPC call to multiple servers, returning either a Vec of responses,
/// or an error if quorum could not be reached due to too many errors /// or an error if quorum could not be reached due to too many errors
/// ///
/// Contrary to try_call_many, this function is especially made for broadcast /// Contrary to `try_call_many`, this function is especially made for broadcast
/// write operations. In particular: /// write operations. In particular:
/// ///
/// - The request are sent to all specified nodes as soon as `try_write_many_sets` /// - The request are sent to all specified nodes as soon as `try_write_many_sets`
+4 -4
View File
@@ -57,7 +57,7 @@ pub enum SystemRpc {
Ok, Ok,
/// Request to connect to a specific node (in `<pubkey>@<host>:<port>` format, pubkey = full-length node ID) /// Request to connect to a specific node (in `<pubkey>@<host>:<port>` format, pubkey = full-length node ID)
Connect(String), Connect(String),
/// Advertise Garage status. Answered with another AdvertiseStatus. /// Advertise Garage status. Answered with another `AdvertiseStatus`.
/// Exchanged with every node on a regular basis. /// Exchanged with every node on a regular basis.
AdvertiseStatus(NodeStatus), AdvertiseStatus(NodeStatus),
/// Get known nodes states /// Get known nodes states
@@ -65,9 +65,9 @@ pub enum SystemRpc {
/// Return known nodes /// Return known nodes
ReturnKnownNodes(Vec<KnownNodeInfo>), ReturnKnownNodes(Vec<KnownNodeInfo>),
/// Ask other node its cluster layout. Answered with AdvertiseClusterLayout /// Ask other node its cluster layout. Answered with `AdvertiseClusterLayout`
PullClusterLayout, PullClusterLayout,
/// Advertisement of cluster layout. Sent spontanously or in response to PullClusterLayout /// Advertisement of cluster layout. Sent spontanously or in response to `PullClusterLayout`
AdvertiseClusterLayout(LayoutHistory), AdvertiseClusterLayout(LayoutHistory),
/// Ask other node its cluster layout update trackers. /// Ask other node its cluster layout update trackers.
PullClusterLayoutTrackers, PullClusterLayoutTrackers,
@@ -908,7 +908,7 @@ impl NodeStatus {
} }
/// Obtain the list of currently available IP addresses on all non-loopback /// Obtain the list of currently available IP addresses on all non-loopback
/// interfaces, optionally filtering them to be inside a given IpNet. /// interfaces, optionally filtering them to be inside a given `IpNet`.
fn get_default_ip(filter_ipnet: Option<ipnet::IpNet>) -> Option<IpAddr> { fn get_default_ip(filter_ipnet: Option<ipnet::IpNet>) -> Option<IpAddr> {
pnet_datalink::interfaces() pnet_datalink::interfaces()
.into_iter() .into_iter()
+1 -1
View File
@@ -5,7 +5,7 @@ use opentelemetry::{global, metrics::*, KeyValue};
use crate::system::{ClusterHealthStatus, System}; use crate::system::{ClusterHealthStatus, System};
/// TableMetrics reference all counter used for metrics /// `TableMetrics` reference all counter used for metrics
pub struct SystemMetrics { pub struct SystemMetrics {
// Static values // Static values
pub(crate) _garage_build_info: ValueObserver<u64>, pub(crate) _garage_build_info: ValueObserver<u64>,
+5 -5
View File
@@ -334,7 +334,7 @@ impl<F: TableSchema, R: TableReplication> Worker for GcWorker<F, R> {
} }
} }
/// An entry stored in the gc_todo db tree associated with the table /// An entry stored in the `gc_todo` db tree associated with the table
/// Contains helper function for parsing, saving, and removing /// Contains helper function for parsing, saving, and removing
/// such entry in the db /// such entry in the db
/// ///
@@ -352,7 +352,7 @@ pub(crate) struct GcTodoEntry {
} }
impl GcTodoEntry { impl GcTodoEntry {
/// Creates a new GcTodoEntry (not saved in the db) from its components: /// Creates a new `GcTodoEntry` (not saved in the db) from its components:
/// the key of an entry in the table, and the hash of the associated /// the key of an entry in the table, and the hash of the associated
/// serialized value /// serialized value
pub(crate) fn new(key: Vec<u8>, value_hash: Hash) -> Self { pub(crate) fn new(key: Vec<u8>, value_hash: Hash) -> Self {
@@ -364,7 +364,7 @@ impl GcTodoEntry {
} }
} }
/// Parses a GcTodoEntry from a (k, v) pair stored in the gc_todo tree /// Parses a `GcTodoEntry` from a (k, v) pair stored in the `gc_todo` tree
pub(crate) fn parse(db_k: &[u8], db_v: &[u8]) -> Self { pub(crate) fn parse(db_k: &[u8], db_v: &[u8]) -> Self {
Self { Self {
tombstone_timestamp: u64::from_be_bytes(db_k[0..8].try_into().unwrap()), tombstone_timestamp: u64::from_be_bytes(db_k[0..8].try_into().unwrap()),
@@ -374,13 +374,13 @@ impl GcTodoEntry {
} }
} }
/// Saves the GcTodoEntry in the gc_todo tree /// Saves the `GcTodoEntry` in the `gc_todo` tree
pub(crate) fn save(&self, gc_todo_tree: &db::Tree) -> Result<(), Error> { pub(crate) fn save(&self, gc_todo_tree: &db::Tree) -> Result<(), Error> {
gc_todo_tree.insert(self.todo_table_key(), self.value_hash.as_slice())?; gc_todo_tree.insert(self.todo_table_key(), self.value_hash.as_slice())?;
Ok(()) Ok(())
} }
/// Removes the GcTodoEntry from the gc_todo tree if the /// Removes the `GcTodoEntry` from the `gc_todo` tree if the
/// hash of the serialized value is the same here as in the tree. /// hash of the serialized value is the same here as in the tree.
/// This is useful to remove a todo entry only under the condition /// This is useful to remove a todo entry only under the condition
/// that it has not changed since the time it was read, i.e. /// that it has not changed since the time it was read, i.e.
+1 -1
View File
@@ -2,7 +2,7 @@ use opentelemetry::{global, metrics::*, KeyValue};
use garage_db as db; use garage_db as db;
/// TableMetrics reference all counter used for metrics /// `TableMetrics` reference all counter used for metrics
pub struct TableMetrics { pub struct TableMetrics {
pub(crate) _table_size: ValueObserver<u64>, pub(crate) _table_size: ValueObserver<u64>,
pub(crate) _merkle_tree_size: ValueObserver<u64>, pub(crate) _merkle_tree_size: ValueObserver<u64>,
+1 -1
View File
@@ -22,7 +22,7 @@ impl PartitionKey for String {
} }
} }
/// Values of type FixedBytes32 are assumed to be random, /// Values of type `FixedBytes32` are assumed to be random,
/// either a hash or a random UUID. This means we can use /// either a hash or a random UUID. This means we can use
/// them directly as an index into the hash table. /// them directly as an index into the hash table.
impl PartitionKey for FixedBytes32 { impl PartitionKey for FixedBytes32 {
+2 -2
View File
@@ -27,7 +27,7 @@ pub struct WorkerInfo {
pub last_error: Option<(String, u64)>, pub last_error: Option<(String, u64)>,
} }
/// WorkerStatus is a struct returned by the worker with a bunch of canonical /// `WorkerStatus` is a struct returned by the worker with a bunch of canonical
/// fields to indicate their status to CLI users. All fields are optional. /// fields to indicate their status to CLI users. All fields are optional.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct WorkerStatus { pub struct WorkerStatus {
@@ -39,7 +39,7 @@ pub struct WorkerStatus {
} }
impl BackgroundRunner { impl BackgroundRunner {
/// Create a new BackgroundRunner /// Create a new `BackgroundRunner`
pub fn new(stop_signal: watch::Receiver<bool>) -> (Arc<Self>, tokio::task::JoinHandle<()>) { pub fn new(stop_signal: watch::Receiver<bool>) -> (Arc<Self>, tokio::task::JoinHandle<()>) {
let (send_worker, worker_out) = mpsc::unbounded_channel::<Box<dyn Worker>>(); let (send_worker, worker_out) = mpsc::unbounded_channel::<Box<dyn Worker>>();
+2 -2
View File
@@ -34,11 +34,11 @@ pub trait Worker: Send {
} }
/// Work: do a basic unit of work, if one is available (otherwise, should return /// Work: do a basic unit of work, if one is available (otherwise, should return
/// WorkerState::Idle immediately). We will do our best to not interrupt this future in the /// `WorkerState::Idle` immediately). We will do our best to not interrupt this future in the
/// middle of processing, it will only be interrupted at the last minute when Garage is trying /// middle of processing, it will only be interrupted at the last minute when Garage is trying
/// to exit and this hasn't returned yet. This function may return an error to indicate that /// to exit and this hasn't returned yet. This function may return an error to indicate that
/// its unit of work could not be processed due to an error: the error will be logged and /// its unit of work could not be processed due to an error: the error will be logged and
/// .work() will be called again after a short delay. /// .`work()` will be called again after a short delay.
async fn work(&mut self, must_exit: &mut watch::Receiver<bool>) -> Result<WorkerState, Error>; async fn work(&mut self, must_exit: &mut watch::Receiver<bool>) -> Result<WorkerState, Error>;
/// Wait for work: await for some task to become available. This future can be interrupted in /// Wait for work: await for some task to become available. This future can be interrupted in
+4 -4
View File
@@ -47,7 +47,7 @@ pub struct Config {
/// Maximum number of parallel block writes per PUT request /// Maximum number of parallel block writes per PUT request
/// Higher values improve throughput but increase memory usage /// Higher values improve throughput but increase memory usage
/// Default: 3, Recommended: 10-30 for NVMe, 3-10 for HDD /// Default: 3, Recommended: 10-30 for `NVMe`, 3-10 for HDD
#[serde(default = "default_block_max_concurrent_writes_per_request")] #[serde(default = "default_block_max_concurrent_writes_per_request")]
pub block_max_concurrent_writes_per_request: usize, pub block_max_concurrent_writes_per_request: usize,
/// Number of replicas. Can be any positive integer, but uneven numbers are more favorable. /// Number of replicas. Can be any positive integer, but uneven numbers are more favorable.
@@ -95,7 +95,7 @@ pub struct Config {
pub rpc_secret_file: Option<PathBuf>, pub rpc_secret_file: Option<PathBuf>,
/// Address to bind for RPC /// Address to bind for RPC
pub rpc_bind_addr: SocketAddr, pub rpc_bind_addr: SocketAddr,
/// Bind outgoing sockets to rpc_bind_addr's IP address as well /// Bind outgoing sockets to `rpc_bind_addr`'s IP address as well
#[serde(default)] #[serde(default)]
pub rpc_bind_outgoing: bool, pub rpc_bind_outgoing: bool,
/// Public IP address of this node /// Public IP address of this node
@@ -154,7 +154,7 @@ pub struct Config {
pub allow_punycode: bool, pub allow_punycode: bool,
} }
/// Value for data_dir: either a single directory or a list of dirs with attributes /// Value for `data_dir`: either a single directory or a list of dirs with attributes
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
#[serde(untagged)] #[serde(untagged)]
pub enum DataDirEnum { pub enum DataDirEnum {
@@ -166,7 +166,7 @@ pub enum DataDirEnum {
pub struct DataDir { pub struct DataDir {
/// Path to the data directory /// Path to the data directory
pub path: PathBuf, pub path: PathBuf,
/// Capacity of the drive (required if read_only is false) /// Capacity of the drive (required if `read_only` is false)
#[serde(default)] #[serde(default)]
pub capacity: Option<String>, pub capacity: Option<String>,
/// Whether this is a legacy read-only path (capacity should be None) /// Whether this is a legacy read-only path (capacity should be None)
+4 -4
View File
@@ -29,10 +29,10 @@ pub trait Crdt {
/// `Option<T>` implements Crdt for any type T, even if T doesn't implement CRDT itself: when /// `Option<T>` implements Crdt for any type T, even if T doesn't implement CRDT itself: when
/// different values are detected, they are always merged to None. This can be used for value /// different values are detected, they are always merged to None. This can be used for value
/// types which shoulnd't be merged, instead of trying to merge things when we know we don't want /// types which shoulnd't be merged, instead of trying to merge things when we know we don't want
/// to merge them (which is what the AutoCrdt trait is used for most of the time). This cases /// to merge them (which is what the `AutoCrdt` trait is used for most of the time). This cases
/// arises very often, for example with a Lww or a LwwMap: the value type has to be a CRDT so that /// arises very often, for example with a Lww or a `LwwMap`: the value type has to be a CRDT so that
/// we have a rule for what to do when timestamps aren't enough to disambiguate (in a distributed /// we have a rule for what to do when timestamps aren't enough to disambiguate (in a distributed
/// system, anything can happen!), and with AutoCrdt the rule is to make an arbitrary (but /// system, anything can happen!), and with `AutoCrdt` the rule is to make an arbitrary (but
/// deterministic) choice between the two. When using an `Option<T>` instead with this impl, ambiguity /// deterministic) choice between the two. When using an `Option<T>` instead with this impl, ambiguity
/// cases are explicitly stored as None, which allows us to detect the ambiguity and handle it in /// cases are explicitly stored as None, which allows us to detect the ambiguity and handle it in
/// the way we want. (this can only work if we are happy with losing the value when an ambiguity /// the way we want. (this can only work if we are happy with losing the value when an ambiguity
@@ -52,7 +52,7 @@ where
/// defined by the merge rule: `a ⊔ b = max(a, b)`. Implement this trait for your type /// defined by the merge rule: `a ⊔ b = max(a, b)`. Implement this trait for your type
/// to enable this behavior. /// to enable this behavior.
pub trait AutoCrdt: Ord + Clone + std::fmt::Debug { pub trait AutoCrdt: Ord + Clone + std::fmt::Debug {
/// WARN_IF_DIFFERENT: emit a warning when values differ. Set this to true if /// `WARN_IF_DIFFERENT`: emit a warning when values differ. Set this to true if
/// different values in your application should never happen. Set this to false /// different values in your application should never happen. Set this to false
/// if you are actually relying on the semantics of `a ⊔ b = max(a, b)`. /// if you are actually relying on the semantics of `a ⊔ b = max(a, b)`.
const WARN_IF_DIFFERENT: bool; const WARN_IF_DIFFERENT: bool;
+1 -1
View File
@@ -19,7 +19,7 @@ use crate::crdt::crdt::*;
/// Internally, the map is stored as a vector of keys and values, sorted by ascending key order. /// Internally, the map is stored as a vector of keys and values, sorted by ascending key order.
/// This is why the key type `K` must implement `Ord` (and also to ensure a unique serialization, /// This is why the key type `K` must implement `Ord` (and also to ensure a unique serialization,
/// such that two values can be compared for equality based on their hashes). As a consequence, /// such that two values can be compared for equality based on their hashes). As a consequence,
/// insertions take `O(n)` time. This means that LWWMap should be used for reasonably small maps. /// insertions take `O(n)` time. This means that `LWWMap` should be used for reasonably small maps.
/// However, note that even if we were using a more efficient data structure such as a `BTreeMap`, /// However, note that even if we were using a more efficient data structure such as a `BTreeMap`,
/// the serialization cost `O(n)` would still have to be paid at each modification, so we are /// the serialization cost `O(n)` would still have to be paid at each modification, so we are
/// actually not losing anything here. /// actually not losing anything here.
+1 -1
View File
@@ -73,7 +73,7 @@ impl FixedBytes32 {
pub fn to_vec(self) -> Vec<u8> { pub fn to_vec(self) -> Vec<u8> {
self.0.to_vec() self.0.to_vec()
} }
/// Try building a FixedBytes32 from a slice /// Try building a `FixedBytes32` from a slice
/// Return None if the slice is not 32 bytes long /// Return None if the slice is not 32 bytes long
pub fn try_from(by: &[u8]) -> Option<Self> { pub fn try_from(by: &[u8]) -> Option<Self> {
if by.len() != 32 { if by.len() != 32 {
+4 -4
View File
@@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Serialize to MessagePack, without versioning /// Serialize to `MessagePack`, without versioning
/// (see garage_util::migrate for functions that manage versioned /// (see `garage_util::migrate` for functions that manage versioned
/// data formats) /// data formats)
pub fn nonversioned_encode<T>(val: &T) -> Result<Vec<u8>, rmp_serde::encode::Error> pub fn nonversioned_encode<T>(val: &T) -> Result<Vec<u8>, rmp_serde::encode::Error>
where where
@@ -13,8 +13,8 @@ where
Ok(wr) Ok(wr)
} }
/// Deserialize from MessagePack, without versioning /// Deserialize from `MessagePack`, without versioning
/// (see garage_util::migrate for functions that manage versioned /// (see `garage_util::migrate` for functions that manage versioned
/// data formats) /// data formats)
pub fn nonversioned_decode<T>(bytes: &[u8]) -> Result<T, rmp_serde::decode::Error> pub fn nonversioned_decode<T>(bytes: &[u8]) -> Result<T, rmp_serde::decode::Error>
where where
+1 -1
View File
@@ -129,7 +129,7 @@ where
} }
} }
/// Trait to map any error type to Error::Message /// Trait to map any error type to `Error::Message`
pub trait OkOrMessage { pub trait OkOrMessage {
type S; type S;
fn ok_or_message<M: Into<String>>(self, message: M) -> Result<Self::S, Error>; fn ok_or_message<M: Into<String>>(self, message: M) -> Result<Self::S, Error>;
+1 -1
View File
@@ -54,7 +54,7 @@ impl<T: InitialFormat> Migrate for T {
} }
} }
/// Internal type used by InitialFormat, not meant for general use. /// Internal type used by `InitialFormat`, not meant for general use.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub enum NoPrevious {} pub enum NoPrevious {}