mirror of
https://github.com/deuxfleurs-org/garage.git
synced 2026-07-26 07:58:14 +00:00
define a separate enum for the monotonic/non-monotonic read flag
This commit is contained in:
@@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
|
||||
use garage_table::{EnumerationOrder, TableSchema};
|
||||
|
||||
use garage_model::k2v::item_table::*;
|
||||
use garage_model::k2v::rpc::K2VMonotonicRead;
|
||||
|
||||
use garage_api_common::helpers::*;
|
||||
|
||||
@@ -68,7 +69,7 @@ pub async fn handle_read_batch(
|
||||
async fn handle_read_batch_query(
|
||||
ctx: &ReqCtx,
|
||||
query: ReadBatchQuery,
|
||||
monotonic_read: bool,
|
||||
monotonic_read: K2VMonotonicRead,
|
||||
) -> Result<ReadBatchResponse, Error> {
|
||||
let ReqCtx {
|
||||
garage, bucket_id, ..
|
||||
@@ -92,10 +93,11 @@ async fn handle_read_batch_query(
|
||||
.start
|
||||
.as_ref()
|
||||
.ok_or_bad_request("start should be specified if single_item is set")?;
|
||||
let item = if monotonic_read {
|
||||
garage.k2v.item_table.get_monotonic(&partition, sk).await?
|
||||
} else {
|
||||
garage.k2v.item_table.get(&partition, sk).await?
|
||||
let item = match monotonic_read {
|
||||
K2VMonotonicRead::Monotonic => {
|
||||
garage.k2v.item_table.get_monotonic(&partition, sk).await?
|
||||
}
|
||||
K2VMonotonicRead::NonMonotonic => garage.k2v.item_table.get(&partition, sk).await?,
|
||||
}
|
||||
.filter(|e| K2VItemTable::matches_filter(e, &filter));
|
||||
match item {
|
||||
|
||||
+16
-14
@@ -5,6 +5,7 @@ use hyper::{Request, Response, StatusCode};
|
||||
|
||||
use garage_model::k2v::causality::*;
|
||||
use garage_model::k2v::item_table::*;
|
||||
use garage_model::k2v::rpc::K2VMonotonicRead;
|
||||
|
||||
use garage_api_common::helpers::*;
|
||||
|
||||
@@ -24,19 +25,17 @@ pub(crate) fn parse_causality_token(s: &str) -> Result<CausalContext, Error> {
|
||||
CausalContext::parse(s).ok_or(Error::InvalidCausalityToken)
|
||||
}
|
||||
|
||||
pub(crate) fn is_monotonic_read(req: &Request<ReqBody>) -> Result<bool, Error> {
|
||||
pub(crate) fn is_monotonic_read(req: &Request<ReqBody>) -> Result<K2VMonotonicRead, Error> {
|
||||
let v_opt = req
|
||||
.headers()
|
||||
.get(X_GARAGE_NON_MONOTONIC_READ)
|
||||
.map(|s| s.to_str())
|
||||
.transpose()?;
|
||||
|
||||
// The header is set to 'true' if the read may be *non*-monotonic,
|
||||
// and this function returns if we must do a *monotonic* read; hence
|
||||
// the boolean negation.
|
||||
match v_opt {
|
||||
Some("true") => Ok(false),
|
||||
Some("false") | None => Ok(true),
|
||||
Some("true") => Ok(K2VMonotonicRead::NonMonotonic),
|
||||
// Reads are monotonic by default
|
||||
Some("false") | None => Ok(K2VMonotonicRead::Monotonic),
|
||||
Some(s) => Err(Error::InvalidNonMonotonicRead(s.to_string())),
|
||||
}
|
||||
}
|
||||
@@ -133,14 +132,17 @@ pub async fn handle_read_item(
|
||||
partition_key: partition_key.to_string(),
|
||||
};
|
||||
|
||||
let item = if monotonic_read {
|
||||
garage
|
||||
.k2v
|
||||
.item_table
|
||||
.get_monotonic(&partition_key, sort_key)
|
||||
.await?
|
||||
} else {
|
||||
garage.k2v.item_table.get(&partition_key, sort_key).await?
|
||||
let item = match monotonic_read {
|
||||
K2VMonotonicRead::Monotonic => {
|
||||
garage
|
||||
.k2v
|
||||
.item_table
|
||||
.get_monotonic(&partition_key, sort_key)
|
||||
.await?
|
||||
}
|
||||
K2VMonotonicRead::NonMonotonic => {
|
||||
garage.k2v.item_table.get(&partition_key, sort_key).await?
|
||||
}
|
||||
}
|
||||
.ok_or(Error::NoSuchKey)?;
|
||||
|
||||
|
||||
+10
-4
@@ -38,6 +38,12 @@ const POLL_RANGE_EXTRA_DELAY: Duration = Duration::from_millis(200);
|
||||
|
||||
const TIMESTAMP_KEY: &[u8] = b"timestamp";
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum K2VMonotonicRead {
|
||||
Monotonic,
|
||||
NonMonotonic,
|
||||
}
|
||||
|
||||
/// RPC messages for K2V
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
enum K2VRpc {
|
||||
@@ -210,7 +216,7 @@ impl K2VRpcHandler {
|
||||
sort_key: String,
|
||||
causal_context: CausalContext,
|
||||
timeout_msec: u64,
|
||||
monotonic_read: bool,
|
||||
monotonic_read: K2VMonotonicRead,
|
||||
) -> Result<Option<K2VItem>, Error> {
|
||||
let poll_key = PollKey {
|
||||
partition: K2VItemPartition {
|
||||
@@ -272,7 +278,7 @@ impl K2VRpcHandler {
|
||||
}
|
||||
|
||||
if let Some(v) = &resp {
|
||||
if monotonic_read && not_all_same {
|
||||
if monotonic_read == K2VMonotonicRead::Monotonic && not_all_same {
|
||||
self.item_table.repair_on_read(&nodes, &[&v]).await?;
|
||||
}
|
||||
}
|
||||
@@ -285,7 +291,7 @@ impl K2VRpcHandler {
|
||||
range: PollRange,
|
||||
seen_str: Option<String>,
|
||||
timeout_msec: u64,
|
||||
monotonic_read: bool,
|
||||
monotonic_read: K2VMonotonicRead,
|
||||
) -> Result<Option<(BTreeMap<String, K2VItem>, String)>, HelperError> {
|
||||
let has_seen_marker = seen_str.is_some();
|
||||
|
||||
@@ -402,7 +408,7 @@ impl K2VRpcHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if monotonic_read && !to_repair.is_empty() {
|
||||
if monotonic_read == K2VMonotonicRead::Monotonic && !to_repair.is_empty() {
|
||||
let to_repair: Vec<_> = to_repair
|
||||
.into_iter()
|
||||
.map(|k| new_items.get(&k).unwrap())
|
||||
|
||||
Reference in New Issue
Block a user