summaryrefslogtreecommitdiffstats
path: root/src/remake/coordinator.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/remake/coordinator.rs')
-rw-r--r--src/remake/coordinator.rs30
1 files changed, 20 insertions, 10 deletions
diff --git a/src/remake/coordinator.rs b/src/remake/coordinator.rs
index 9bcf8ba..3a7b071 100644
--- a/src/remake/coordinator.rs
+++ b/src/remake/coordinator.rs
@@ -141,7 +141,23 @@ fn obstacle(id: &str, record: &Record, all: &[(String, Record)]) -> Option<Strin
}
async fn commit<H: Host>(host: &H, id: &str, record: &Record) -> Result<(), StoreError> {
- let Some(mut request) = record.snapshot_request(id) else {
+ let content = match &record.proposal.content {
+ Some(reference) => match content::ensure(host, reference).await {
+ Ok(bytes) => Some(bytes),
+ Err(reason) => return decide_abort(host, id, reason).await,
+ },
+ None => None,
+ };
+
+ // Clone under the read lock, build without any lock.
+ let mut copy = host.read_doc(|doc| doc.clone()).await;
+ // A base left to the commit is what this node has now. Every node that sees the
+ // decision has it too: the decision change depends on it.
+ let (base, fixed_now) = match &record.proposal.base_heads {
+ None => (Some(copy.get_heads()), true),
+ Some(heads) => (records::decode_heads(heads), false),
+ };
+ let Some(mut request) = base.and_then(|base| record.snapshot_request_at(id, base)) else {
return decide_abort(
host,
id,
@@ -149,15 +165,8 @@ async fn commit<H: Host>(host: &H, id: &str, record: &Record) -> Result<(), Stor
)
.await;
};
- if let Some(reference) = &record.proposal.content {
- match content::ensure(host, reference).await {
- Ok(bytes) => request.content = Some(bytes),
- Err(reason) => return decide_abort(host, id, reason).await,
- }
- }
-
- // Clone under the read lock, build without any lock.
- let copy = host.read_doc(|doc| doc.clone()).await;
+ let base_heads = fixed_now.then(|| records::encode_heads(&request.base_heads));
+ request.content = content;
let mut snapshot = match snapshot::build_detached(copy, request).await {
Ok((snapshot, _copy)) => snapshot,
Err(error) => {
@@ -170,6 +179,7 @@ async fn commit<H: Host>(host: &H, id: &str, record: &Record) -> Result<(), Stor
let decision = Decision::Committed {
to_epoch: to_epoch.into(),
+ base_heads,
snapshot_bytes,
decided_at: records::unix_millis(),
};