Radish alpha
r
Radicle Job Collaborative Object
Radicle
Git (anonymous pull)
Log in to clone via SSH
feat: add function to announce changes to other nodes
✗ CI failure Lars Wirzenius committed 10 months ago
commit 4eaf59cde82eba7b3ae52c6322d9da5b7c17a32a
parent 574129a2d0008294818aa99ba99b3ad64ffdaeab
1 passed 2 failed (3 total) View logs
2 files changed +61 -3
modified src/error.rs
@@ -47,3 +47,17 @@ pub enum Apply {
    #[error(transparent)]
    Op(#[from] cob::op::OpEncodingError),
}
+

+
/// Errors that can occur when announcing changes to other nodes.
+
#[derive(Debug, Error)]
+
pub enum Announce {
+
    /// Getting seeds for a repository.
+
    #[error("failed to get seeds for a repository")]
+
    Seeds(#[source] radicle::node::Error),
+
    /// Creating a COB announcer.
+
    #[error("failed to create a COB announcer")]
+
    Announcer,
+
    /// Announcing changes.
+
    #[error("failed to announce COB change")]
+
    Announce(#[source] radicle::node::Error),
+
}
modified src/lib.rs
@@ -49,10 +49,11 @@

#![deny(missing_docs)]

-
use std::collections::HashMap;
+
use std::collections::{BTreeSet, HashMap};
use std::fmt;
use std::ops::{Deref, DerefMut};
use std::str::FromStr;
+
use std::time::Duration;

use indexmap::IndexMap;
use once_cell::sync::Lazy;
@@ -61,8 +62,11 @@ use radicle::cob::{self, store, EntryId, Evaluate, ObjectId, Op, TypeName};
use radicle::crypto;
use radicle::crypto::signature::Signer;
use radicle::node::device::Device;
-
use radicle::node::NodeId;
-
use radicle::prelude::ReadRepository;
+
use radicle::node::{
+
    sync::{Announcer, AnnouncerConfig, ReplicationFactor},
+
    Handle, Node, NodeId,
+
};
+
use radicle::prelude::{Profile, ReadRepository, RepoId};
use radicle::storage::{RepositoryError, SignRepository, WriteRepository};
use radicle::{cob::store::CobAction, git::Oid};
use serde::{Deserialize, Serialize};
@@ -817,6 +821,46 @@ where
    }
}

+
/// Ask node to announce any changes to a repository to other nodes.
+
///
+
/// Call this after making changes to COBs so that the changes get
+
/// propagated to the Radicle network as soon as possible.
+
pub fn announce(profile: &Profile, repo_id: RepoId) -> Result<(), error::Announce> {
+
    const TIMEOUT: Duration = Duration::from_millis(5000);
+

+
    let mut node = Node::new(profile.home.socket());
+

+
    let (synced, unsynced) = node
+
        .seeds(repo_id)
+
        .map_err(error::Announce::Seeds)?
+
        .iter()
+
        .fold(
+
            (BTreeSet::new(), BTreeSet::new()),
+
            |(mut synced, mut unsynced), seed| {
+
                if seed.is_synced() {
+
                    synced.insert(seed.nid);
+
                } else {
+
                    unsynced.insert(seed.nid);
+
                }
+
                (synced, unsynced)
+
            },
+
        );
+

+
    let announcer = Announcer::new(AnnouncerConfig::public(
+
        *profile.id(),
+
        ReplicationFactor::MustReach(1),
+
        BTreeSet::new(),
+
        synced,
+
        unsynced,
+
    ))
+
    .map_err(|_| error::Announce::Announcer)?;
+

+
    node.announce(repo_id, TIMEOUT, announcer, |_, _| ())
+
        .map_err(error::Announce::Announce)?;
+

+
    Ok(())
+
}
+

#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod test {