Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: Don't announce if already in sync
cloudhead committed 2 years ago
commit b140d8580fb00e22e08fb5b9a755fcf13fe3cf74
parent d4ec2176bbbec9eac876af5bd06c46e651c64b14
3 files changed +62 -19
modified radicle-cli/examples/rad-sync.md
@@ -28,11 +28,11 @@ $ rad sync --announce
```

If we try to sync again after the nodes have synced, we will already
-
be up to date and so we will see the same message.
+
be up to date.

```
$ rad sync --announce
-
✓ Synced with 2 node(s)
+
✓ Nothing to announce, already in sync with network (see `rad sync status`)
```

We can also use the `--fetch` option to only fetch objects:
@@ -51,7 +51,7 @@ $ rad sync --fetch --announce
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6Mkux1…nVhib7Z..
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6Mkt67…v4N1tRk..
✓ Fetched repository from 2 seed(s)
-
✓ Synced with 2 node(s)
+
✓ Nothing to announce, already in sync with network (see `rad sync status`)
```

It's also possible to use the `--seed` flag to only sync with a specific node:
modified radicle-cli/src/commands/sync.rs
@@ -328,16 +328,46 @@ fn sync_status(rid: Id, node: &mut Node) -> anyhow::Result<()> {

fn announce_refs(
    rid: Id,
-
    _mode: RepoSync,
+
    mode: RepoSync,
    timeout: time::Duration,
    mut node: Node,
    profile: &Profile,
) -> anyhow::Result<()> {
    let repo = profile.storage.repository(rid)?;
    let doc = repo.identity_doc()?;
-
    let connected: Vec<_> = if doc.visibility.is_public() {
+
    let unsynced: Vec<_> = if doc.visibility.is_public() {
        let seeds = node.seeds(rid)?;
-
        seeds.connected().map(|s| s.nid).collect()
+
        let synced = seeds.iter().filter(|s| s.is_synced());
+

+
        match mode {
+
            RepoSync::Seeds(seeds) => {
+
                let synced = synced.map(|s| s.nid).collect::<Vec<_>>();
+
                if seeds.iter().all(|s| synced.contains(s)) {
+
                    term::success!(
+
                        "Already in sync with the specified seed(s) (see `rad sync status`)"
+
                    );
+
                    return Ok(());
+
                }
+
            }
+
            RepoSync::Replicas(replicas) => {
+
                let count = synced.count();
+
                if count >= seeds.len() {
+
                    term::success!(
+
                        "Nothing to announce, already in sync with network (see `rad sync status`)"
+
                    );
+
                    return Ok(());
+
                }
+
                if count >= replicas {
+
                    term::success!("Nothing to announce, already in sync with {count} seed(s) (see `rad sync status`)");
+
                    return Ok(());
+
                }
+
            }
+
        }
+
        seeds
+
            .connected()
+
            .filter(|s| !s.is_synced())
+
            .map(|s| s.nid)
+
            .collect()
    } else {
        node.sessions()?
            .into_iter()
@@ -346,13 +376,13 @@ fn announce_refs(
            .collect()
    };

-
    if connected.is_empty() {
-
        term::info!("Not connected to any seeds.");
+
    if unsynced.is_empty() {
+
        term::info!("Not connected to any seeds for {rid}.");
        return Ok(());
    }

-
    let mut spinner = term::spinner(format!("Syncing with {} node(s)..", connected.len()));
-
    let result = node.announce(rid, connected, timeout, |event| match event {
+
    let mut spinner = term::spinner(format!("Syncing with {} node(s)..", unsynced.len()));
+
    let result = node.announce(rid, unsynced, timeout, |event| match event {
        node::AnnounceEvent::Announced => {}
        node::AnnounceEvent::RefsSynced { remote } => {
            spinner.message(format!("Synced with {remote}.."));
modified radicle/src/node.rs
@@ -460,6 +460,11 @@ impl Seed {
        matches!(self.state, Some(State::Connected { .. }))
    }

+
    /// Check if this seed is in sync with us.
+
    pub fn is_synced(&self) -> bool {
+
        matches!(self.sync, Some(SyncStatus::Synced { .. }))
+
    }
+

    pub fn new(
        nid: NodeId,
        addrs: Vec<KnownAddress>,
@@ -497,22 +502,30 @@ impl Seeds {
        self.0.contains_key(nid)
    }

+
    /// Number of seeds.
+
    pub fn len(&self) -> usize {
+
        self.0.len()
+
    }
+

+
    /// Check if there are any seeds.
+
    pub fn is_empty(&self) -> bool {
+
        self.0.is_empty()
+
    }
+

    /// Partitions the list of seeds into connected and disconnected seeds.
    /// Note that the disconnected seeds may be in a "connecting" state.
    pub fn partition(&self) -> (Vec<Seed>, Vec<Seed>) {
-
        self.0
-
            .shuffled()
-
            .map(|(_, v)| v)
-
            .cloned()
-
            .partition(|s| s.is_connected())
+
        self.iter().cloned().partition(|s| s.is_connected())
    }

    /// Return connected seeds.
    pub fn connected(&self) -> impl Iterator<Item = &Seed> {
-
        self.0
-
            .shuffled()
-
            .map(|(_, v)| v)
-
            .filter(|s| s.is_connected())
+
        self.iter().filter(|s| s.is_connected())
+
    }
+

+
    /// Return all seeds.
+
    pub fn iter(&self) -> impl Iterator<Item = &Seed> {
+
        self.0.shuffled().map(|(_, v)| v)
    }

    /// Check if a seed is connected.