aboutsummaryrefslogtreecommitdiffstats
path: root/src/swarm/document_file.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/swarm/document_file.rs')
-rw-r--r--src/swarm/document_file.rs17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/swarm/document_file.rs b/src/swarm/document_file.rs
index 4c7843d..c833656 100644
--- a/src/swarm/document_file.rs
+++ b/src/swarm/document_file.rs
@@ -28,6 +28,7 @@ pub(crate) async fn run(state: AppState) {
/// At a clean stop, after the last `flush`: the file marked as holding everything this
/// node wrote (`DocumentFile::close`), where it does (ready, not rejoining, up to the
/// document's heads), so a restart may write on as the same actor (`--keep-actor`).
+/// The node writes as a fresh actor from then on.
pub(crate) async fn close(state: &AppState) {
let Some(file) = state.document_file.clone() else {
return;
@@ -35,8 +36,20 @@ pub(crate) async fn close(state: &AppState) {
if state.remake.is_rejoining() || !state.is_ready().await {
return;
}
- let heads = state.doc.read().await.doc.get_heads();
- file.close(&heads);
+ // Under the write lock, and leaving the document with a fresh actor: whatever the
+ // node still writes until it exits (its alive stamp, a vote, a coordinator's commit:
+ // nothing stops them) is no change of the actor the file marks as complete.
+ let doc = Arc::clone(&state.doc);
+ let closed = tokio::task::spawn_blocking(move || {
+ let mut replica = doc.blocking_write();
+ let heads = replica.doc.get_heads();
+ file.close(&heads);
+ replica.doc.set_actor(crate::document::ActorId::random());
+ })
+ .await;
+ if let Err(error) = closed {
+ tracing::error!(error = %error, "Marking the document file as closed failed");
+ }
}
/// Writes what is due now (`DocumentFile::due`). Also called at shutdown.