mirror of
https://github.com/deuxfleurs-org/garage.git
synced 2026-08-07 21:33:13 +00:00
rename types to CamelCase
This commit is contained in:
committed by
Alex Auvolat
parent
6644df6b96
commit
e4b9e4e24d
@@ -27,7 +27,7 @@ impl From<bool> for Bool {
|
||||
}
|
||||
}
|
||||
|
||||
impl CRDT for Bool {
|
||||
impl Crdt for Bool {
|
||||
fn merge(&mut self, other: &Self) {
|
||||
self.0 = self.0 || other.0;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ use garage_util::data::*;
|
||||
/// Moreover, the relationship `≥` defined by `a ≥ b ⇔ ∃c. a = b ⊔ c` must be a partial order.
|
||||
/// This implies a few properties such as: if `a ⊔ b ≠ a`, then there is no `c` such that `(a ⊔ b) ⊔ c = a`,
|
||||
/// as this would imply a cycle in the partial order.
|
||||
pub trait CRDT {
|
||||
pub trait Crdt {
|
||||
/// Merge the two datastructures according to the CRDT rules.
|
||||
/// `self` is modified to contain the merged CRDT value. `other` is not modified.
|
||||
///
|
||||
@@ -31,16 +31,16 @@ pub trait CRDT {
|
||||
/// All types that implement `Ord` (a total order) can also implement a trivial CRDT
|
||||
/// defined by the merge rule: `a ⊔ b = max(a, b)`. Implement this trait for your type
|
||||
/// 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
|
||||
/// 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)`.
|
||||
const WARN_IF_DIFFERENT: bool;
|
||||
}
|
||||
|
||||
impl<T> CRDT for T
|
||||
impl<T> Crdt for T
|
||||
where
|
||||
T: AutoCRDT,
|
||||
T: AutoCrdt,
|
||||
{
|
||||
fn merge(&mut self, other: &Self) {
|
||||
if Self::WARN_IF_DIFFERENT && self != other {
|
||||
@@ -58,14 +58,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl AutoCRDT for String {
|
||||
impl AutoCrdt for String {
|
||||
const WARN_IF_DIFFERENT: bool = true;
|
||||
}
|
||||
|
||||
impl AutoCRDT for bool {
|
||||
impl AutoCrdt for bool {
|
||||
const WARN_IF_DIFFERENT: bool = true;
|
||||
}
|
||||
|
||||
impl AutoCRDT for FixedBytes32 {
|
||||
impl AutoCrdt for FixedBytes32 {
|
||||
const WARN_IF_DIFFERENT: bool = true;
|
||||
}
|
||||
|
||||
@@ -36,14 +36,14 @@ use crate::crdt::crdt::*;
|
||||
/// This scheme is used by AWS S3 or Soundcloud and often without knowing
|
||||
/// in enterprise when reconciliating databases with ad-hoc scripts.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct LWW<T> {
|
||||
pub struct Lww<T> {
|
||||
ts: u64,
|
||||
v: T,
|
||||
}
|
||||
|
||||
impl<T> LWW<T>
|
||||
impl<T> Lww<T>
|
||||
where
|
||||
T: CRDT,
|
||||
T: Crdt,
|
||||
{
|
||||
/// Creates a new CRDT
|
||||
///
|
||||
@@ -99,9 +99,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> CRDT for LWW<T>
|
||||
impl<T> Crdt for Lww<T>
|
||||
where
|
||||
T: Clone + CRDT,
|
||||
T: Clone + Crdt,
|
||||
{
|
||||
fn merge(&mut self, other: &Self) {
|
||||
if other.ts > self.ts {
|
||||
|
||||
@@ -22,14 +22,14 @@ use crate::crdt::crdt::*;
|
||||
/// the serialization cost `O(n)` would still have to be paid at each modification, so we are
|
||||
/// actually not losing anything here.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct LWWMap<K, V> {
|
||||
pub struct LwwMap<K, V> {
|
||||
vals: Vec<(K, u64, V)>,
|
||||
}
|
||||
|
||||
impl<K, V> LWWMap<K, V>
|
||||
impl<K, V> LwwMap<K, V>
|
||||
where
|
||||
K: Ord,
|
||||
V: CRDT,
|
||||
V: Crdt,
|
||||
{
|
||||
/// Create a new empty map CRDT
|
||||
pub fn new() -> Self {
|
||||
@@ -125,10 +125,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> CRDT for LWWMap<K, V>
|
||||
impl<K, V> Crdt for LwwMap<K, V>
|
||||
where
|
||||
K: Clone + Ord,
|
||||
V: Clone + CRDT,
|
||||
V: Clone + Crdt,
|
||||
{
|
||||
fn merge(&mut self, other: &Self) {
|
||||
for (k, ts2, v2) in other.vals.iter() {
|
||||
@@ -150,10 +150,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> Default for LWWMap<K, V>
|
||||
impl<K, V> Default for LwwMap<K, V>
|
||||
where
|
||||
K: Ord,
|
||||
V: CRDT,
|
||||
V: Crdt,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
|
||||
@@ -22,7 +22,7 @@ pub struct Map<K, V> {
|
||||
impl<K, V> Map<K, V>
|
||||
where
|
||||
K: Clone + Ord,
|
||||
V: Clone + CRDT,
|
||||
V: Clone + Crdt,
|
||||
{
|
||||
/// Create a new empty map CRDT
|
||||
pub fn new() -> Self {
|
||||
@@ -69,10 +69,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> CRDT for Map<K, V>
|
||||
impl<K, V> Crdt for Map<K, V>
|
||||
where
|
||||
K: Clone + Ord,
|
||||
V: Clone + CRDT,
|
||||
V: Clone + Crdt,
|
||||
{
|
||||
fn merge(&mut self, other: &Self) {
|
||||
for (k, v2) in other.vals.iter() {
|
||||
@@ -91,7 +91,7 @@ where
|
||||
impl<K, V> Default for Map<K, V>
|
||||
where
|
||||
K: Clone + Ord,
|
||||
V: Clone + CRDT,
|
||||
V: Clone + Crdt,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ use garage_util::error::*;
|
||||
|
||||
use garage_rpc::membership::System;
|
||||
|
||||
use crate::crdt::CRDT;
|
||||
use crate::crdt::Crdt;
|
||||
use crate::replication::*;
|
||||
use crate::schema::*;
|
||||
|
||||
@@ -151,7 +151,7 @@ where
|
||||
|
||||
if Some(&new_entry) != old_entry.as_ref() {
|
||||
let new_bytes = rmp_to_vec_all_named(&new_entry)
|
||||
.map_err(Error::RMPEncode)
|
||||
.map_err(Error::RmpEncode)
|
||||
.map_err(sled::transaction::ConflictableTransactionError::Abort)?;
|
||||
let new_bytes_hash = blake2sum(&new_bytes[..]);
|
||||
mkl_todo.insert(tree_key.clone(), new_bytes_hash.as_slice())?;
|
||||
|
||||
+15
-15
@@ -24,23 +24,23 @@ use crate::schema::*;
|
||||
const TABLE_GC_BATCH_SIZE: usize = 1024;
|
||||
const TABLE_GC_RPC_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
||||
pub struct TableGC<F: TableSchema, R: TableReplication> {
|
||||
pub struct TableGc<F: TableSchema, R: TableReplication> {
|
||||
system: Arc<System>,
|
||||
data: Arc<TableData<F, R>>,
|
||||
|
||||
rpc_client: Arc<RpcClient<GcRPC>>,
|
||||
rpc_client: Arc<RpcClient<GcRpc>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
enum GcRPC {
|
||||
enum GcRpc {
|
||||
Update(Vec<ByteBuf>),
|
||||
DeleteIfEqualHash(Vec<(ByteBuf, Hash)>),
|
||||
Ok,
|
||||
}
|
||||
|
||||
impl RpcMessage for GcRPC {}
|
||||
impl RpcMessage for GcRpc {}
|
||||
|
||||
impl<F, R> TableGC<F, R>
|
||||
impl<F, R> TableGc<F, R>
|
||||
where
|
||||
F: TableSchema + 'static,
|
||||
R: TableReplication + 'static,
|
||||
@@ -51,7 +51,7 @@ where
|
||||
rpc_server: &mut RpcServer,
|
||||
) -> Arc<Self> {
|
||||
let rpc_path = format!("table_{}/gc", data.name);
|
||||
let rpc_client = system.rpc_client::<GcRPC>(&rpc_path);
|
||||
let rpc_client = system.rpc_client::<GcRpc>(&rpc_path);
|
||||
|
||||
let gc = Arc::new(Self {
|
||||
system: system.clone(),
|
||||
@@ -168,7 +168,7 @@ where
|
||||
|
||||
async fn try_send_and_delete(
|
||||
&self,
|
||||
nodes: Vec<UUID>,
|
||||
nodes: Vec<Uuid>,
|
||||
items: Vec<(ByteBuf, Hash, ByteBuf)>,
|
||||
) -> Result<(), Error> {
|
||||
let n_items = items.len();
|
||||
@@ -183,7 +183,7 @@ where
|
||||
self.rpc_client
|
||||
.try_call_many(
|
||||
&nodes[..],
|
||||
GcRPC::Update(updates),
|
||||
GcRpc::Update(updates),
|
||||
RequestStrategy::with_quorum(nodes.len()).with_timeout(TABLE_GC_RPC_TIMEOUT),
|
||||
)
|
||||
.await?;
|
||||
@@ -196,7 +196,7 @@ where
|
||||
self.rpc_client
|
||||
.try_call_many(
|
||||
&nodes[..],
|
||||
GcRPC::DeleteIfEqualHash(deletes.clone()),
|
||||
GcRpc::DeleteIfEqualHash(deletes.clone()),
|
||||
RequestStrategy::with_quorum(nodes.len()).with_timeout(TABLE_GC_RPC_TIMEOUT),
|
||||
)
|
||||
.await?;
|
||||
@@ -221,7 +221,7 @@ where
|
||||
|
||||
fn register_handler(self: &Arc<Self>, rpc_server: &mut RpcServer, path: String) {
|
||||
let self2 = self.clone();
|
||||
rpc_server.add_handler::<GcRPC, _, _>(path, move |msg, _addr| {
|
||||
rpc_server.add_handler::<GcRpc, _, _>(path, move |msg, _addr| {
|
||||
let self2 = self2.clone();
|
||||
async move { self2.handle_rpc(&msg).await }
|
||||
});
|
||||
@@ -234,18 +234,18 @@ where
|
||||
});
|
||||
}
|
||||
|
||||
async fn handle_rpc(self: &Arc<Self>, message: &GcRPC) -> Result<GcRPC, Error> {
|
||||
async fn handle_rpc(self: &Arc<Self>, message: &GcRpc) -> Result<GcRpc, Error> {
|
||||
match message {
|
||||
GcRPC::Update(items) => {
|
||||
GcRpc::Update(items) => {
|
||||
self.data.update_many(items)?;
|
||||
Ok(GcRPC::Ok)
|
||||
Ok(GcRpc::Ok)
|
||||
}
|
||||
GcRPC::DeleteIfEqualHash(items) => {
|
||||
GcRpc::DeleteIfEqualHash(items) => {
|
||||
for (key, vhash) in items.iter() {
|
||||
self.data.delete_if_equal_hash(&key[..], *vhash)?;
|
||||
self.todo_remove_if_equal(&key[..], *vhash)?;
|
||||
}
|
||||
Ok(GcRPC::Ok)
|
||||
Ok(GcRpc::Ok)
|
||||
}
|
||||
_ => Err(Error::Message("Unexpected GC RPC".to_string())),
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#![recursion_limit = "1024"]
|
||||
#![allow(clippy::comparison_chain, clippy::upper_case_acronyms)]
|
||||
#![allow(clippy::comparison_chain)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
@@ -19,14 +19,14 @@ pub struct TableFullReplication {
|
||||
}
|
||||
|
||||
impl TableReplication for TableFullReplication {
|
||||
fn read_nodes(&self, _hash: &Hash) -> Vec<UUID> {
|
||||
fn read_nodes(&self, _hash: &Hash) -> Vec<Uuid> {
|
||||
vec![self.system.id]
|
||||
}
|
||||
fn read_quorum(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn write_nodes(&self, _hash: &Hash) -> Vec<UUID> {
|
||||
fn write_nodes(&self, _hash: &Hash) -> Vec<Uuid> {
|
||||
let ring = self.system.ring.borrow();
|
||||
ring.config.members.keys().cloned().collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ pub trait TableReplication: Send + Sync {
|
||||
// To understand various replication methods
|
||||
|
||||
/// Which nodes to send read requests to
|
||||
fn read_nodes(&self, hash: &Hash) -> Vec<UUID>;
|
||||
fn read_nodes(&self, hash: &Hash) -> Vec<Uuid>;
|
||||
/// Responses needed to consider a read succesfull
|
||||
fn read_quorum(&self) -> usize;
|
||||
|
||||
/// Which nodes to send writes to
|
||||
fn write_nodes(&self, hash: &Hash) -> Vec<UUID>;
|
||||
fn write_nodes(&self, hash: &Hash) -> Vec<Uuid>;
|
||||
/// Responses needed to consider a write succesfull
|
||||
fn write_quorum(&self) -> usize;
|
||||
fn max_write_errors(&self) -> usize;
|
||||
|
||||
@@ -25,7 +25,7 @@ pub struct TableShardedReplication {
|
||||
}
|
||||
|
||||
impl TableReplication for TableShardedReplication {
|
||||
fn read_nodes(&self, hash: &Hash) -> Vec<UUID> {
|
||||
fn read_nodes(&self, hash: &Hash) -> Vec<Uuid> {
|
||||
let ring = self.system.ring.borrow().clone();
|
||||
ring.walk_ring(&hash, self.replication_factor)
|
||||
}
|
||||
@@ -33,7 +33,7 @@ impl TableReplication for TableShardedReplication {
|
||||
self.read_quorum
|
||||
}
|
||||
|
||||
fn write_nodes(&self, hash: &Hash) -> Vec<UUID> {
|
||||
fn write_nodes(&self, hash: &Hash) -> Vec<Uuid> {
|
||||
let ring = self.system.ring.borrow();
|
||||
ring.walk_ring(&hash, self.replication_factor)
|
||||
}
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use garage_util::data::*;
|
||||
|
||||
use crate::crdt::CRDT;
|
||||
use crate::crdt::Crdt;
|
||||
|
||||
/// Trait for field used to partition data
|
||||
pub trait PartitionKey {
|
||||
@@ -42,7 +42,7 @@ impl SortKey for Hash {
|
||||
|
||||
/// Trait for an entry in a table. It must be sortable and partitionnable.
|
||||
pub trait Entry<P: PartitionKey, S: SortKey>:
|
||||
CRDT + PartialEq + Clone + Serialize + for<'de> Deserialize<'de> + Send + Sync
|
||||
Crdt + PartialEq + Clone + Serialize + for<'de> Deserialize<'de> + Send + Sync
|
||||
{
|
||||
/// Get the key used to partition
|
||||
fn partition_key(&self) -> &P;
|
||||
|
||||
+23
-23
@@ -34,11 +34,11 @@ pub struct TableSyncer<F: TableSchema, R: TableReplication> {
|
||||
merkle: Arc<MerkleUpdater<F, R>>,
|
||||
|
||||
todo: Mutex<SyncTodo>,
|
||||
rpc_client: Arc<RpcClient<SyncRPC>>,
|
||||
rpc_client: Arc<RpcClient<SyncRpc>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub(crate) enum SyncRPC {
|
||||
pub(crate) enum SyncRpc {
|
||||
RootCkHash(Partition, Hash),
|
||||
RootCkDifferent(bool),
|
||||
GetNode(MerkleNodeKey),
|
||||
@@ -47,7 +47,7 @@ pub(crate) enum SyncRPC {
|
||||
Ok,
|
||||
}
|
||||
|
||||
impl RpcMessage for SyncRPC {}
|
||||
impl RpcMessage for SyncRpc {}
|
||||
|
||||
struct SyncTodo {
|
||||
todo: Vec<TodoPartition>,
|
||||
@@ -75,7 +75,7 @@ where
|
||||
rpc_server: &mut RpcServer,
|
||||
) -> Arc<Self> {
|
||||
let rpc_path = format!("table_{}/sync", data.name);
|
||||
let rpc_client = system.rpc_client::<SyncRPC>(&rpc_path);
|
||||
let rpc_client = system.rpc_client::<SyncRpc>(&rpc_path);
|
||||
|
||||
let todo = SyncTodo { todo: vec![] };
|
||||
|
||||
@@ -114,7 +114,7 @@ where
|
||||
|
||||
fn register_handler(self: &Arc<Self>, rpc_server: &mut RpcServer, path: String) {
|
||||
let self2 = self.clone();
|
||||
rpc_server.add_handler::<SyncRPC, _, _>(path, move |msg, _addr| {
|
||||
rpc_server.add_handler::<SyncRpc, _, _>(path, move |msg, _addr| {
|
||||
let self2 = self2.clone();
|
||||
async move { self2.handle_rpc(&msg).await }
|
||||
});
|
||||
@@ -317,14 +317,14 @@ where
|
||||
async fn offload_items(
|
||||
self: &Arc<Self>,
|
||||
items: &[(Vec<u8>, Arc<ByteBuf>)],
|
||||
nodes: &[UUID],
|
||||
nodes: &[Uuid],
|
||||
) -> Result<(), Error> {
|
||||
let values = items.iter().map(|(_k, v)| v.clone()).collect::<Vec<_>>();
|
||||
|
||||
self.rpc_client
|
||||
.try_call_many(
|
||||
nodes,
|
||||
SyncRPC::Items(values),
|
||||
SyncRpc::Items(values),
|
||||
RequestStrategy::with_quorum(nodes.len()).with_timeout(TABLE_SYNC_RPC_TIMEOUT),
|
||||
)
|
||||
.await?;
|
||||
@@ -362,7 +362,7 @@ where
|
||||
async fn do_sync_with(
|
||||
self: Arc<Self>,
|
||||
partition: TodoPartition,
|
||||
who: UUID,
|
||||
who: Uuid,
|
||||
must_exit: watch::Receiver<bool>,
|
||||
) -> Result<(), Error> {
|
||||
let (root_ck_key, root_ck) = self.get_root_ck(partition.partition)?;
|
||||
@@ -381,20 +381,20 @@ where
|
||||
.rpc_client
|
||||
.call(
|
||||
who,
|
||||
SyncRPC::RootCkHash(partition.partition, root_ck_hash),
|
||||
SyncRpc::RootCkHash(partition.partition, root_ck_hash),
|
||||
TABLE_SYNC_RPC_TIMEOUT,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let mut todo = match root_resp {
|
||||
SyncRPC::RootCkDifferent(false) => {
|
||||
SyncRpc::RootCkDifferent(false) => {
|
||||
debug!(
|
||||
"({}) Sync {:?} with {:?}: no difference",
|
||||
self.data.name, partition, who
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
SyncRPC::RootCkDifferent(true) => VecDeque::from(vec![root_ck_key]),
|
||||
SyncRpc::RootCkDifferent(true) => VecDeque::from(vec![root_ck_key]),
|
||||
x => {
|
||||
return Err(Error::Message(format!(
|
||||
"Invalid respone to RootCkHash RPC: {}",
|
||||
@@ -431,10 +431,10 @@ where
|
||||
// and compare it with local node
|
||||
let remote_node = match self
|
||||
.rpc_client
|
||||
.call(who, SyncRPC::GetNode(key.clone()), TABLE_SYNC_RPC_TIMEOUT)
|
||||
.call(who, SyncRpc::GetNode(key.clone()), TABLE_SYNC_RPC_TIMEOUT)
|
||||
.await?
|
||||
{
|
||||
SyncRPC::Node(_, node) => node,
|
||||
SyncRpc::Node(_, node) => node,
|
||||
x => {
|
||||
return Err(Error::Message(format!(
|
||||
"Invalid respone to GetNode RPC: {}",
|
||||
@@ -478,7 +478,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn send_items(&self, who: UUID, item_value_list: Vec<Vec<u8>>) -> Result<(), Error> {
|
||||
async fn send_items(&self, who: Uuid, item_value_list: Vec<Vec<u8>>) -> Result<(), Error> {
|
||||
info!(
|
||||
"({}) Sending {} items to {:?}",
|
||||
self.data.name,
|
||||
@@ -493,9 +493,9 @@ where
|
||||
|
||||
let rpc_resp = self
|
||||
.rpc_client
|
||||
.call(who, SyncRPC::Items(values), TABLE_SYNC_RPC_TIMEOUT)
|
||||
.call(who, SyncRpc::Items(values), TABLE_SYNC_RPC_TIMEOUT)
|
||||
.await?;
|
||||
if let SyncRPC::Ok = rpc_resp {
|
||||
if let SyncRpc::Ok = rpc_resp {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::Message(format!(
|
||||
@@ -507,20 +507,20 @@ where
|
||||
|
||||
// ======= SYNCHRONIZATION PROCEDURE -- RECEIVER SIDE ======
|
||||
|
||||
async fn handle_rpc(self: &Arc<Self>, message: &SyncRPC) -> Result<SyncRPC, Error> {
|
||||
async fn handle_rpc(self: &Arc<Self>, message: &SyncRpc) -> Result<SyncRpc, Error> {
|
||||
match message {
|
||||
SyncRPC::RootCkHash(range, h) => {
|
||||
SyncRpc::RootCkHash(range, h) => {
|
||||
let (_root_ck_key, root_ck) = self.get_root_ck(*range)?;
|
||||
let hash = hash_of::<MerkleNode>(&root_ck)?;
|
||||
Ok(SyncRPC::RootCkDifferent(hash != *h))
|
||||
Ok(SyncRpc::RootCkDifferent(hash != *h))
|
||||
}
|
||||
SyncRPC::GetNode(k) => {
|
||||
SyncRpc::GetNode(k) => {
|
||||
let node = self.merkle.read_node(&k)?;
|
||||
Ok(SyncRPC::Node(k.clone(), node))
|
||||
Ok(SyncRpc::Node(k.clone(), node))
|
||||
}
|
||||
SyncRPC::Items(items) => {
|
||||
SyncRpc::Items(items) => {
|
||||
self.data.update_many(items)?;
|
||||
Ok(SyncRPC::Ok)
|
||||
Ok(SyncRpc::Ok)
|
||||
}
|
||||
_ => Err(Error::Message("Unexpected sync RPC".to_string())),
|
||||
}
|
||||
|
||||
+23
-23
@@ -13,7 +13,7 @@ use garage_rpc::membership::System;
|
||||
use garage_rpc::rpc_client::*;
|
||||
use garage_rpc::rpc_server::*;
|
||||
|
||||
use crate::crdt::CRDT;
|
||||
use crate::crdt::Crdt;
|
||||
use crate::data::*;
|
||||
use crate::gc::*;
|
||||
use crate::merkle::*;
|
||||
@@ -28,11 +28,11 @@ pub struct Table<F: TableSchema, R: TableReplication> {
|
||||
pub data: Arc<TableData<F, R>>,
|
||||
pub merkle_updater: Arc<MerkleUpdater<F, R>>,
|
||||
pub syncer: Arc<TableSyncer<F, R>>,
|
||||
rpc_client: Arc<RpcClient<TableRPC<F>>>,
|
||||
rpc_client: Arc<RpcClient<TableRpc<F>>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub(crate) enum TableRPC<F: TableSchema> {
|
||||
pub(crate) enum TableRpc<F: TableSchema> {
|
||||
Ok,
|
||||
|
||||
ReadEntry(F::P, F::S),
|
||||
@@ -44,7 +44,7 @@ pub(crate) enum TableRPC<F: TableSchema> {
|
||||
Update(Vec<Arc<ByteBuf>>),
|
||||
}
|
||||
|
||||
impl<F: TableSchema> RpcMessage for TableRPC<F> {}
|
||||
impl<F: TableSchema> RpcMessage for TableRpc<F> {}
|
||||
|
||||
impl<F, R> Table<F, R>
|
||||
where
|
||||
@@ -62,7 +62,7 @@ where
|
||||
rpc_server: &mut RpcServer,
|
||||
) -> Arc<Self> {
|
||||
let rpc_path = format!("table_{}", name);
|
||||
let rpc_client = system.rpc_client::<TableRPC<F>>(&rpc_path);
|
||||
let rpc_client = system.rpc_client::<TableRpc<F>>(&rpc_path);
|
||||
|
||||
let data = TableData::new(system.clone(), name, instance, replication, db);
|
||||
|
||||
@@ -74,7 +74,7 @@ where
|
||||
merkle_updater.clone(),
|
||||
rpc_server,
|
||||
);
|
||||
TableGC::launch(system.clone(), data.clone(), rpc_server);
|
||||
TableGc::launch(system.clone(), data.clone(), rpc_server);
|
||||
|
||||
let table = Arc::new(Self {
|
||||
system,
|
||||
@@ -95,7 +95,7 @@ where
|
||||
//eprintln!("insert who: {:?}", who);
|
||||
|
||||
let e_enc = Arc::new(ByteBuf::from(rmp_to_vec_all_named(e)?));
|
||||
let rpc = TableRPC::<F>::Update(vec![e_enc]);
|
||||
let rpc = TableRpc::<F>::Update(vec![e_enc]);
|
||||
|
||||
self.rpc_client
|
||||
.try_call_many(
|
||||
@@ -121,7 +121,7 @@ where
|
||||
}
|
||||
|
||||
let call_futures = call_list.drain().map(|(node, entries)| async move {
|
||||
let rpc = TableRPC::<F>::Update(entries);
|
||||
let rpc = TableRpc::<F>::Update(entries);
|
||||
|
||||
let resp = self.rpc_client.call(node, rpc, TABLE_RPC_TIMEOUT).await?;
|
||||
Ok::<_, Error>((node, resp))
|
||||
@@ -150,7 +150,7 @@ where
|
||||
let who = self.data.replication.read_nodes(&hash);
|
||||
//eprintln!("get who: {:?}", who);
|
||||
|
||||
let rpc = TableRPC::<F>::ReadEntry(partition_key.clone(), sort_key.clone());
|
||||
let rpc = TableRpc::<F>::ReadEntry(partition_key.clone(), sort_key.clone());
|
||||
let resps = self
|
||||
.rpc_client
|
||||
.try_call_many(
|
||||
@@ -165,7 +165,7 @@ where
|
||||
let mut ret = None;
|
||||
let mut not_all_same = false;
|
||||
for resp in resps {
|
||||
if let TableRPC::ReadEntryResponse(value) = resp {
|
||||
if let TableRpc::ReadEntryResponse(value) = resp {
|
||||
if let Some(v_bytes) = value {
|
||||
let v = self.data.decode_entry(v_bytes.as_slice())?;
|
||||
ret = match ret {
|
||||
@@ -205,7 +205,7 @@ where
|
||||
let hash = partition_key.hash();
|
||||
let who = self.data.replication.read_nodes(&hash);
|
||||
|
||||
let rpc = TableRPC::<F>::ReadRange(partition_key.clone(), begin_sort_key, filter, limit);
|
||||
let rpc = TableRpc::<F>::ReadRange(partition_key.clone(), begin_sort_key, filter, limit);
|
||||
|
||||
let resps = self
|
||||
.rpc_client
|
||||
@@ -221,7 +221,7 @@ where
|
||||
let mut ret = BTreeMap::new();
|
||||
let mut to_repair = BTreeMap::new();
|
||||
for resp in resps {
|
||||
if let TableRPC::Update(entries) = resp {
|
||||
if let TableRpc::Update(entries) = resp {
|
||||
for entry_bytes in entries.iter() {
|
||||
let entry = self.data.decode_entry(entry_bytes.as_slice())?;
|
||||
let entry_key = self.data.tree_key(entry.partition_key(), entry.sort_key());
|
||||
@@ -261,12 +261,12 @@ where
|
||||
|
||||
// =============== UTILITY FUNCTION FOR CLIENT OPERATIONS ===============
|
||||
|
||||
async fn repair_on_read(&self, who: &[UUID], what: F::E) -> Result<(), Error> {
|
||||
async fn repair_on_read(&self, who: &[Uuid], what: F::E) -> Result<(), Error> {
|
||||
let what_enc = Arc::new(ByteBuf::from(rmp_to_vec_all_named(&what)?));
|
||||
self.rpc_client
|
||||
.try_call_many(
|
||||
who,
|
||||
TableRPC::<F>::Update(vec![what_enc]),
|
||||
TableRpc::<F>::Update(vec![what_enc]),
|
||||
RequestStrategy::with_quorum(who.len()).with_timeout(TABLE_RPC_TIMEOUT),
|
||||
)
|
||||
.await?;
|
||||
@@ -277,7 +277,7 @@ where
|
||||
|
||||
fn register_handler(self: Arc<Self>, rpc_server: &mut RpcServer, path: String) {
|
||||
let self2 = self.clone();
|
||||
rpc_server.add_handler::<TableRPC<F>, _, _>(path, move |msg, _addr| {
|
||||
rpc_server.add_handler::<TableRpc<F>, _, _>(path, move |msg, _addr| {
|
||||
let self2 = self2.clone();
|
||||
async move { self2.handle(&msg).await }
|
||||
});
|
||||
@@ -290,21 +290,21 @@ where
|
||||
});
|
||||
}
|
||||
|
||||
async fn handle(self: &Arc<Self>, msg: &TableRPC<F>) -> Result<TableRPC<F>, Error> {
|
||||
async fn handle(self: &Arc<Self>, msg: &TableRpc<F>) -> Result<TableRpc<F>, Error> {
|
||||
match msg {
|
||||
TableRPC::ReadEntry(key, sort_key) => {
|
||||
TableRpc::ReadEntry(key, sort_key) => {
|
||||
let value = self.data.read_entry(key, sort_key)?;
|
||||
Ok(TableRPC::ReadEntryResponse(value))
|
||||
Ok(TableRpc::ReadEntryResponse(value))
|
||||
}
|
||||
TableRPC::ReadRange(key, begin_sort_key, filter, limit) => {
|
||||
TableRpc::ReadRange(key, begin_sort_key, filter, limit) => {
|
||||
let values = self.data.read_range(key, begin_sort_key, filter, *limit)?;
|
||||
Ok(TableRPC::Update(values))
|
||||
Ok(TableRpc::Update(values))
|
||||
}
|
||||
TableRPC::Update(pairs) => {
|
||||
TableRpc::Update(pairs) => {
|
||||
self.data.update_many(pairs)?;
|
||||
Ok(TableRPC::Ok)
|
||||
Ok(TableRpc::Ok)
|
||||
}
|
||||
_ => Err(Error::BadRPC("Unexpected table RPC".to_string())),
|
||||
_ => Err(Error::BadRpc("Unexpected table RPC".to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user