mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-15 19:30:38 +08:00
cob: Remove CRDTs from COB state
It turns out that the CRDT formed by the union of Git DAGs is enough to guarantee everything we need for COBs. This changes the following things: * COB operations no longer need to be commutative * COB histories are traversed in the same deterministic order on all replicas * It's now possible to implement RSMs on top of COBs, eg. scripting * Lamport clocks have been removed * `radicle-crdt` is no longer a dependency of `radicle` * COBs are no longer instances of `Semilattice` * The `Ops` type was removed in favor of having `Op` contain multiple actions
This commit is contained in:
@@ -138,7 +138,7 @@ pub(crate) fn patch(
|
||||
"discussions": rev.discussion().comments()
|
||||
.map(|(id, comment)| Comment::new(id, comment, aliases))
|
||||
.collect::<Vec<_>>(),
|
||||
"timestamp": rev.timestamp(),
|
||||
"timestamp": rev.timestamp().as_secs().to_string(),
|
||||
"reviews": rev.reviews().map(|(nid, _review)| review(nid, aliases.alias(nid), _review)).collect::<Vec<_>>(),
|
||||
})
|
||||
}).collect::<Vec<_>>(),
|
||||
@@ -165,7 +165,7 @@ fn merge(merge: &Merge, nid: &NodeId, alias: Option<Alias>) -> Value {
|
||||
"alias": alias,
|
||||
},
|
||||
"commit": merge.commit,
|
||||
"timestamp": merge.timestamp,
|
||||
"timestamp": merge.timestamp.as_secs().to_string(),
|
||||
"revision": merge.revision,
|
||||
}),
|
||||
None => json!({
|
||||
@@ -173,7 +173,7 @@ fn merge(merge: &Merge, nid: &NodeId, alias: Option<Alias>) -> Value {
|
||||
"id": nid,
|
||||
},
|
||||
"commit": merge.commit,
|
||||
"timestamp": merge.timestamp,
|
||||
"timestamp": merge.timestamp.as_secs().to_string(),
|
||||
"revision": merge.revision,
|
||||
}),
|
||||
}
|
||||
@@ -190,7 +190,7 @@ fn review(nid: &NodeId, alias: Option<Alias>, review: &Review) -> Value {
|
||||
"verdict": review.verdict(),
|
||||
"summary": review.summary(),
|
||||
"comments": review.comments().collect::<Vec<_>>(),
|
||||
"timestamp": review.timestamp(),
|
||||
"timestamp": review.timestamp().as_secs().to_string(),
|
||||
}),
|
||||
None => json!({
|
||||
"author": {
|
||||
@@ -199,7 +199,7 @@ fn review(nid: &NodeId, alias: Option<Alias>, review: &Review) -> Value {
|
||||
"verdict": review.verdict(),
|
||||
"summary": review.summary(),
|
||||
"comments": review.comments().collect::<Vec<_>>(),
|
||||
"timestamp": review.timestamp(),
|
||||
"timestamp": review.timestamp().as_secs().to_string(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -240,6 +240,7 @@ struct Comment<'a> {
|
||||
author: Value,
|
||||
body: &'a str,
|
||||
reactions: Vec<(&'a ActorId, &'a Reaction)>,
|
||||
#[serde(with = "radicle::serde_ext::localtime::time")]
|
||||
timestamp: Timestamp,
|
||||
reply_to: Option<CommentId>,
|
||||
}
|
||||
|
||||
@@ -460,16 +460,16 @@ async fn issues_handler(
|
||||
let mut issues: Vec<_> = issues
|
||||
.all()?
|
||||
.filter_map(|r| {
|
||||
let (id, issue, clock) = r.ok()?;
|
||||
(state.matches(issue.state())).then_some((id, issue, clock))
|
||||
let (id, issue) = r.ok()?;
|
||||
(state.matches(issue.state())).then_some((id, issue))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
issues.sort_by(|(_, a, _), (_, b, _)| b.timestamp().cmp(&a.timestamp()));
|
||||
issues.sort_by(|(_, a), (_, b)| b.timestamp().cmp(&a.timestamp()));
|
||||
let aliases = &ctx.profile.aliases();
|
||||
let issues = issues
|
||||
.into_iter()
|
||||
.map(|(id, issue, _)| api::json::issue(id, issue, aliases))
|
||||
.map(|(id, issue)| api::json::issue(id, issue, aliases))
|
||||
.skip(page * per_page)
|
||||
.take(per_page)
|
||||
.collect::<Vec<_>>();
|
||||
@@ -739,15 +739,15 @@ async fn patches_handler(
|
||||
let mut patches = patches
|
||||
.all()?
|
||||
.filter_map(|r| {
|
||||
let (id, patch, clock) = r.ok()?;
|
||||
(state.matches(patch.state())).then_some((id, patch, clock))
|
||||
let (id, patch) = r.ok()?;
|
||||
(state.matches(patch.state())).then_some((id, patch))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
patches.sort_by(|(_, a, _), (_, b, _)| b.timestamp().cmp(&a.timestamp()));
|
||||
patches.sort_by(|(_, a), (_, b)| b.timestamp().cmp(&a.timestamp()));
|
||||
let aliases = ctx.profile.aliases();
|
||||
let patches = patches
|
||||
.into_iter()
|
||||
.map(|(id, patch, _)| api::json::patch(id, patch, &repo, &aliases))
|
||||
.map(|(id, patch)| api::json::patch(id, patch, &repo, &aliases))
|
||||
.skip(page * per_page)
|
||||
.take(per_page)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -37,7 +37,7 @@ pub const ISSUE_ID: &str = "5ad77fa3f476beed9a26f49b2b3b844e61bef792";
|
||||
pub const ISSUE_DISCUSSION_ID: &str = "f1dff128a22e8183a23516dd9812e72e80914c92";
|
||||
pub const ISSUE_COMMENT_ID: &str = "845218041bf9eb8155bfa4aaa8f0c91ce18e5c13";
|
||||
pub const SESSION_ID: &str = "u9MGAkkfkMOv0uDDB2WeUHBT7HbsO2Dy";
|
||||
pub const TIMESTAMP: u64 = 1671125284;
|
||||
pub const TIMESTAMP: &str = "1671125284";
|
||||
pub const CONTRIBUTOR_RID: &str = "rad:z4XaCmN3jLSeiMvW15YTDpNbDHFhG";
|
||||
pub const CONTRIBUTOR_DID: &str = "did:key:z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8";
|
||||
pub const CONTRIBUTOR_NID: &str = "z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8";
|
||||
@@ -97,7 +97,7 @@ fn seed_with_signer<G: Signer>(dir: &Path, profile: radicle::Profile, signer: &G
|
||||
|
||||
let workdir = dir.join("hello-world");
|
||||
|
||||
env::set_var("RAD_COMMIT_TIME", TIMESTAMP.to_string());
|
||||
env::set_var("RAD_COMMIT_TIME", TIMESTAMP);
|
||||
|
||||
fs::create_dir_all(&workdir).unwrap();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user