rename Operation to ReplicaOp for clarity

This commit is contained in:
Dustin J. Mitchell
2021-12-19 20:03:01 +00:00
parent 6f7794c7de
commit 0b29efab31
9 changed files with 120 additions and 119 deletions

View File

@@ -1,5 +1,5 @@
use crate::server::{Server, SyncOp};
use crate::storage::{Operation, Storage, TaskMap};
use crate::storage::{ReplicaOp, Storage, TaskMap};
use uuid::Uuid;
mod ops;
@@ -31,7 +31,7 @@ impl TaskDb {
/// Apply an operation to the TaskDb. Aside from synchronization operations, this is the only way
/// to modify the TaskDb. In cases where an operation does not make sense, this function will do
/// nothing and return an error (but leave the TaskDb in a consistent state).
pub fn apply(&mut self, op: Operation) -> anyhow::Result<()> {
pub fn apply(&mut self, op: ReplicaOp) -> anyhow::Result<()> {
// TODO: differentiate error types here?
let mut txn = self.storage.txn()?;
if let err @ Err(_) = ops::apply_op(txn.as_mut(), &op) {
@@ -46,14 +46,14 @@ impl TaskDb {
pub fn apply_sync_tmp(&mut self, op: SyncOp) -> anyhow::Result<()> {
// create an op from SyncOp
let op = match op {
SyncOp::Create { uuid } => Operation::Create { uuid },
SyncOp::Delete { uuid } => Operation::Delete { uuid },
SyncOp::Create { uuid } => ReplicaOp::Create { uuid },
SyncOp::Delete { uuid } => ReplicaOp::Delete { uuid },
SyncOp::Update {
uuid,
property,
value,
timestamp,
} => Operation::Update {
} => ReplicaOp::Update {
uuid,
property,
value,
@@ -158,7 +158,7 @@ impl TaskDb {
}
#[cfg(test)]
pub(crate) fn operations(&mut self) -> Vec<Operation> {
pub(crate) fn operations(&mut self) -> Vec<ReplicaOp> {
let mut txn = self.storage.txn().unwrap();
txn.operations()
.unwrap()
@@ -184,7 +184,7 @@ mod tests {
// operations; more detailed tests are in the `ops` module.
let mut db = TaskDb::new_inmemory();
let uuid = Uuid::new_v4();
let op = Operation::Create { uuid };
let op = ReplicaOp::Create { uuid };
db.apply(op.clone()).unwrap();
assert_eq!(db.sorted_tasks(), vec![(uuid, vec![]),]);
@@ -197,7 +197,7 @@ mod tests {
#[derive(Debug)]
enum Action {
Op(Operation),
Op(ReplicaOp),
Sync,
}
@@ -209,14 +209,14 @@ mod tests {
.chunks(2)
.map(|action_on| {
let action = match action_on[0] {
b'C' => Action::Op(Operation::Create { uuid }),
b'U' => Action::Op(Operation::Update {
b'C' => Action::Op(ReplicaOp::Create { uuid }),
b'U' => Action::Op(ReplicaOp::Update {
uuid,
property: "title".into(),
value: Some("foo".into()),
timestamp: Utc::now(),
}),
b'D' => Action::Op(Operation::Delete { uuid }),
b'D' => Action::Op(ReplicaOp::Delete { uuid }),
b'S' => Action::Sync,
_ => unreachable!(),
};

View File

@@ -1,20 +1,20 @@
use crate::errors::Error;
use crate::storage::{Operation, StorageTxn};
use crate::storage::{ReplicaOp, StorageTxn};
pub(super) fn apply_op(txn: &mut dyn StorageTxn, op: &Operation) -> anyhow::Result<()> {
pub(super) fn apply_op(txn: &mut dyn StorageTxn, op: &ReplicaOp) -> anyhow::Result<()> {
match op {
Operation::Create { uuid } => {
ReplicaOp::Create { uuid } => {
// insert if the task does not already exist
if !txn.create_task(*uuid)? {
return Err(Error::Database(format!("Task {} already exists", uuid)).into());
}
}
Operation::Delete { ref uuid } => {
ReplicaOp::Delete { ref uuid } => {
if !txn.delete_task(*uuid)? {
return Err(Error::Database(format!("Task {} does not exist", uuid)).into());
}
}
Operation::Update {
ReplicaOp::Update {
ref uuid,
ref property,
ref value,
@@ -49,7 +49,7 @@ mod tests {
fn test_apply_create() -> anyhow::Result<()> {
let mut db = TaskDb::new_inmemory();
let uuid = Uuid::new_v4();
let op = Operation::Create { uuid };
let op = ReplicaOp::Create { uuid };
{
let mut txn = db.storage.txn()?;
@@ -65,7 +65,7 @@ mod tests {
fn test_apply_create_exists() -> anyhow::Result<()> {
let mut db = TaskDb::new_inmemory();
let uuid = Uuid::new_v4();
let op = Operation::Create { uuid };
let op = ReplicaOp::Create { uuid };
{
let mut txn = db.storage.txn()?;
apply_op(txn.as_mut(), &op)?;
@@ -86,7 +86,7 @@ mod tests {
fn test_apply_create_update() -> anyhow::Result<()> {
let mut db = TaskDb::new_inmemory();
let uuid = Uuid::new_v4();
let op1 = Operation::Create { uuid };
let op1 = ReplicaOp::Create { uuid };
{
let mut txn = db.storage.txn()?;
@@ -94,7 +94,7 @@ mod tests {
txn.commit()?;
}
let op2 = Operation::Update {
let op2 = ReplicaOp::Update {
uuid,
property: String::from("title"),
value: Some("my task".into()),
@@ -118,14 +118,14 @@ mod tests {
fn test_apply_create_update_delete_prop() -> anyhow::Result<()> {
let mut db = TaskDb::new_inmemory();
let uuid = Uuid::new_v4();
let op1 = Operation::Create { uuid };
let op1 = ReplicaOp::Create { uuid };
{
let mut txn = db.storage.txn()?;
apply_op(txn.as_mut(), &op1)?;
txn.commit()?;
}
let op2 = Operation::Update {
let op2 = ReplicaOp::Update {
uuid,
property: String::from("title"),
value: Some("my task".into()),
@@ -137,7 +137,7 @@ mod tests {
txn.commit()?;
}
let op3 = Operation::Update {
let op3 = ReplicaOp::Update {
uuid,
property: String::from("priority"),
value: Some("H".into()),
@@ -149,7 +149,7 @@ mod tests {
txn.commit()?;
}
let op4 = Operation::Update {
let op4 = ReplicaOp::Update {
uuid,
property: String::from("title"),
value: None,
@@ -177,7 +177,7 @@ mod tests {
fn test_apply_update_does_not_exist() -> anyhow::Result<()> {
let mut db = TaskDb::new_inmemory();
let uuid = Uuid::new_v4();
let op = Operation::Update {
let op = ReplicaOp::Update {
uuid,
property: String::from("title"),
value: Some("my task".into()),
@@ -199,8 +199,8 @@ mod tests {
fn test_apply_create_delete() -> anyhow::Result<()> {
let mut db = TaskDb::new_inmemory();
let uuid = Uuid::new_v4();
let op1 = Operation::Create { uuid };
let op2 = Operation::Delete { uuid };
let op1 = ReplicaOp::Create { uuid };
let op2 = ReplicaOp::Delete { uuid };
{
let mut txn = db.storage.txn()?;
@@ -218,7 +218,7 @@ mod tests {
fn test_apply_delete_not_present() -> anyhow::Result<()> {
let mut db = TaskDb::new_inmemory();
let uuid = Uuid::new_v4();
let op = Operation::Delete { uuid };
let op = ReplicaOp::Delete { uuid };
{
let mut txn = db.storage.txn()?;
assert_eq!(

View File

@@ -1,6 +1,6 @@
use super::{ops, snapshot};
use crate::server::{AddVersionResult, GetVersionResult, Server, SnapshotUrgency};
use crate::storage::{Operation, StorageTxn};
use crate::storage::{ReplicaOp, StorageTxn};
use crate::Error;
use log::{info, trace, warn};
use serde::{Deserialize, Serialize};
@@ -8,7 +8,7 @@ use std::str;
#[derive(Serialize, Deserialize, Debug)]
struct Version {
operations: Vec<Operation>,
operations: Vec<ReplicaOp>,
}
/// Sync to the given server, pulling remote changes and pushing local changes.
@@ -58,7 +58,7 @@ pub(super) fn sync(
}
}
let operations: Vec<Operation> = txn.operations()?.to_vec();
let operations: Vec<ReplicaOp> = txn.operations()?.to_vec();
if operations.is_empty() {
info!("no changes to push to server");
// nothing to sync back to the server..
@@ -136,7 +136,7 @@ fn apply_version(txn: &mut dyn StorageTxn, mut version: Version) -> anyhow::Resu
// This is slightly complicated by the fact that the transform function can return None,
// indicating no operation is required. If this happens for a local op, we can just omit
// it. If it happens for server op, then we must copy the remaining local ops.
let mut local_operations: Vec<Operation> = txn.operations()?;
let mut local_operations: Vec<ReplicaOp> = txn.operations()?;
for server_op in version.operations.drain(..) {
trace!(
"rebasing local operations onto server operation {:?}",
@@ -146,7 +146,7 @@ fn apply_version(txn: &mut dyn StorageTxn, mut version: Version) -> anyhow::Resu
let mut svr_op = Some(server_op);
for local_op in local_operations.drain(..) {
if let Some(o) = svr_op {
let (new_server_op, new_local_op) = Operation::transform(o, local_op.clone());
let (new_server_op, new_local_op) = ReplicaOp::transform(o, local_op.clone());
trace!("local operation {:?} -> {:?}", local_op, new_local_op);
svr_op = new_server_op;
if let Some(o) = new_local_op {
@@ -175,7 +175,7 @@ fn apply_version(txn: &mut dyn StorageTxn, mut version: Version) -> anyhow::Resu
mod test {
use super::*;
use crate::server::test::TestServer;
use crate::storage::{InMemoryStorage, Operation};
use crate::storage::{InMemoryStorage, ReplicaOp};
use crate::taskdb::{snapshot::SnapshotTasks, TaskDb};
use chrono::Utc;
use pretty_assertions::assert_eq;
@@ -197,8 +197,8 @@ mod test {
// make some changes in parallel to db1 and db2..
let uuid1 = Uuid::new_v4();
db1.apply(Operation::Create { uuid: uuid1 }).unwrap();
db1.apply(Operation::Update {
db1.apply(ReplicaOp::Create { uuid: uuid1 }).unwrap();
db1.apply(ReplicaOp::Update {
uuid: uuid1,
property: "title".into(),
value: Some("my first task".into()),
@@ -207,8 +207,8 @@ mod test {
.unwrap();
let uuid2 = Uuid::new_v4();
db2.apply(Operation::Create { uuid: uuid2 }).unwrap();
db2.apply(Operation::Update {
db2.apply(ReplicaOp::Create { uuid: uuid2 }).unwrap();
db2.apply(ReplicaOp::Update {
uuid: uuid2,
property: "title".into(),
value: Some("my second task".into()),
@@ -223,14 +223,14 @@ mod test {
assert_eq!(db1.sorted_tasks(), db2.sorted_tasks());
// now make updates to the same task on both sides
db1.apply(Operation::Update {
db1.apply(ReplicaOp::Update {
uuid: uuid2,
property: "priority".into(),
value: Some("H".into()),
timestamp: Utc::now(),
})
.unwrap();
db2.apply(Operation::Update {
db2.apply(ReplicaOp::Update {
uuid: uuid2,
property: "project".into(),
value: Some("personal".into()),
@@ -259,8 +259,8 @@ mod test {
// create and update a task..
let uuid = Uuid::new_v4();
db1.apply(Operation::Create { uuid }).unwrap();
db1.apply(Operation::Update {
db1.apply(ReplicaOp::Create { uuid }).unwrap();
db1.apply(ReplicaOp::Update {
uuid,
property: "title".into(),
value: Some("my first task".into()),
@@ -275,9 +275,9 @@ mod test {
assert_eq!(db1.sorted_tasks(), db2.sorted_tasks());
// delete and re-create the task on db1
db1.apply(Operation::Delete { uuid }).unwrap();
db1.apply(Operation::Create { uuid }).unwrap();
db1.apply(Operation::Update {
db1.apply(ReplicaOp::Delete { uuid }).unwrap();
db1.apply(ReplicaOp::Create { uuid }).unwrap();
db1.apply(ReplicaOp::Update {
uuid,
property: "title".into(),
value: Some("my second task".into()),
@@ -286,7 +286,7 @@ mod test {
.unwrap();
// and on db2, update a property of the task
db2.apply(Operation::Update {
db2.apply(ReplicaOp::Update {
uuid,
property: "project".into(),
value: Some("personal".into()),
@@ -310,8 +310,8 @@ mod test {
let mut db1 = newdb();
let uuid = Uuid::new_v4();
db1.apply(Operation::Create { uuid })?;
db1.apply(Operation::Update {
db1.apply(ReplicaOp::Create { uuid })?;
db1.apply(ReplicaOp::Update {
uuid,
property: "title".into(),
value: Some("my first task".into()),
@@ -332,7 +332,7 @@ mod test {
assert_eq!(tasks[0].0, uuid);
// update the taskdb and sync again
db1.apply(Operation::Update {
db1.apply(ReplicaOp::Update {
uuid,
property: "title".into(),
value: Some("my first task, updated".into()),
@@ -362,7 +362,7 @@ mod test {
let mut db1 = newdb();
let uuid = Uuid::new_v4();
db1.apply(Operation::Create { uuid }).unwrap();
db1.apply(ReplicaOp::Create { uuid }).unwrap();
test_server.set_snapshot_urgency(SnapshotUrgency::Low);
sync(&mut server, db1.storage.txn()?.as_mut(), true).unwrap();

View File

@@ -63,7 +63,7 @@ where
#[cfg(test)]
mod test {
use super::*;
use crate::storage::Operation;
use crate::storage::ReplicaOp;
use crate::taskdb::TaskDb;
use chrono::Utc;
use uuid::Uuid;
@@ -94,10 +94,10 @@ mod test {
// add everything to the TaskDb
for uuid in &uuids {
db.apply(Operation::Create { uuid: *uuid })?;
db.apply(ReplicaOp::Create { uuid: *uuid })?;
}
for i in &[0usize, 1, 4] {
db.apply(Operation::Update {
db.apply(ReplicaOp::Update {
uuid: uuids[*i].clone(),
property: String::from("status"),
value: Some("pending".into()),