summaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-25 19:59:14 +0100
committertv <tv@krebsco.de>2026-10-25 19:59:14 +0100
commit72472131a4bb3798759884da597cfb4ef7793782 (patch)
tree5f094dfda00da31e1b564cc033ef5f1d24ba89df /src/main.rs
parent866924934d635df8a8f222a022f806c44581a5f5 (diff)
allow to persist document
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs66
1 files changed, 37 insertions, 29 deletions
diff --git a/src/main.rs b/src/main.rs
index 278a0f4..0a00f1b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,7 +9,7 @@ use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::time::Duration;
-use anyhow::{Context, Result, bail};
+use anyhow::{Context, Result};
use automerge::AutoCommit;
use tokio::sync::{RwLock, broadcast, mpsc, watch};
use tracing::{debug, error, info, trace, warn};
@@ -122,32 +122,27 @@ async fn main() -> Result<()> {
let (change_tx, _) = watch::channel(0_u64);
let (change_events, _) = broadcast::channel(256);
- let recovered = match &args.recover_from {
- Some(path) => Some(bootstrap::load_backup(path, &files)?),
- None => None,
- };
- if let (Some(backup), Some(remembered)) = (&recovered, &remembered) {
- if backup.swarm_id != remembered.swarm_id {
- if !force.allows("swarmId") {
- bail!(
- "The backup is of swarm {}, but the state file remembers swarm {}; add --force swarmId to recover the backup's swarm anyway",
- backup.swarm_id,
- remembered.swarm_id
- );
- }
- warn!(
- backup = %backup.swarm_id,
- remembered = %remembered.swarm_id,
- "The backup is of another swarm than the remembered one; recovering the backup's (--force swarmId)"
- );
- }
- }
- let (initial_doc, recovered_epoch, recovered_swarm) = match recovered {
- Some(backup) => (backup.doc, Some(backup.epoch), Some(backup.swarm_id)),
- None => (AutoCommit::new(), None, None),
+ let starting = bootstrap::starting_document(
+ &bootstrap::StartOptions {
+ recover_from: args.recover_from.as_deref(),
+ document_file: args.document_file.as_deref(),
+ genesis: args.genesis,
+ remembered: remembered.as_ref().map(|r| r.swarm_id.as_str()),
+ },
+ &files,
+ &force,
+ )?;
+ let (initial_doc, starting_epoch, starting_swarm, earlier_actors) = match starting {
+ Some(starting) => (
+ starting.doc,
+ Some(starting.epoch),
+ Some((starting.swarm_id, starting.origin)),
+ starting.earlier_actors,
+ ),
+ None => (AutoCommit::new(), None, None, Vec::new()),
};
let initial_actor = initial_doc.get_actor().clone();
- let initial_epoch = match (recovered_epoch, args.debug_epoch) {
+ let initial_epoch = match (starting_epoch, args.debug_epoch) {
(Some(epoch), _) => epoch,
(None, Some(generation)) => Epoch {
generation,
@@ -197,6 +192,14 @@ async fn main() -> Result<()> {
blobs: Arc::new(swarm::blob::Blobs::new(args.blob_chunk_kib * 1024)),
protocol_writers: Arc::new(args.protocol_writers.iter().cloned().collect()),
state_file,
+ document_file: args.document_file.clone().map(|path| {
+ Arc::new(document::file::DocumentFile::new(
+ path,
+ Arc::clone(&files),
+ Duration::from_secs(args.document_append_secs),
+ Duration::from_secs(args.document_rewrite_secs),
+ ))
+ }),
files,
config: Arc::new(config.report()),
neighbours: Default::default(),
@@ -211,14 +214,17 @@ async fn main() -> Result<()> {
};
trace!("Application state initialized");
+ for actor in earlier_actors {
+ state.remake.add_own_actor(actor);
+ }
state.remake.add_own_actor(initial_actor);
- // Join the remembered swarm and no other; HELLOs claim it. A backup to recover from
+ // Join the remembered swarm and no other; HELLOs claim it. A document to start on
// names its swarm itself (checked against the remembered one above).
- let start = match recovered_swarm {
- Some(swarm_id) => {
+ let start = match starting_swarm {
+ Some((swarm_id, origin)) => {
state.set_expected_swarm_id(swarm_id).await?;
- bootstrap::Start::Recovered
+ bootstrap::Start::FromDocument(origin)
}
None => {
if let Some(remembered) = remembered {
@@ -283,6 +289,7 @@ async fn main() -> Result<()> {
"Bootstrap completed"
);
swarm::state_file::update(&state, true).await;
+ tokio::spawn(document::file::run(state.clone()));
let auth_state = AuthState::new(&args.htpasswd);
let app = api::router(state.clone(), auth_state, args.debug_api);
@@ -328,6 +335,7 @@ async fn main() -> Result<()> {
info!("HTTP API server stopped");
swarm::state_file::update(&stopping, true).await;
+ document::file::flush(&stopping).await;
Ok(())
}