cli: watch for upload-pack events in `rad init`

To improve the user experience of `rad init`, the events listener waits for
upload-pack messages indefinitely. The spinner reports back the upload progress
over time.

This process can be cancelled via Ctrl+C without affecting the announcement,
since that is happening in the background.

To also improve the experience, the remote NIDs that have successfully synced
are reported to the terminal.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
Fintan Halpenny 2024-04-24 15:20:27 +01:00
parent 344fe3a901
commit f038b7ee5c
No known key found for this signature in database
GPG Key ID: C93C17467280C75B
2 changed files with 30 additions and 3 deletions

View File

@ -10,6 +10,7 @@ Initializing public radicle 👾 repository in [..]
Your Repository ID (RID) is rad:z3Rry7rpdWuGpfjPYGzdJKQADsoNW. Your Repository ID (RID) is rad:z3Rry7rpdWuGpfjPYGzdJKQADsoNW.
You can show it any time by running `rad .` from this directory. You can show it any time by running `rad .` from this directory.
✓ Repository successfully synced to z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
✓ Repository successfully synced to 1 node(s). ✓ Repository successfully synced to 1 node(s).
Your repository has been synced to the network and is now discoverable by peers. Your repository has been synced to the network and is now discoverable by peers.

View File

@ -2,10 +2,10 @@
#![allow(clippy::collapsible_else_if)] #![allow(clippy::collapsible_else_if)]
use std::collections::HashSet; use std::collections::HashSet;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::env;
use std::ffi::OsString; use std::ffi::OsString;
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use std::{env, time};
use anyhow::{anyhow, bail, Context as _}; use anyhow::{anyhow, bail, Context as _};
use serde_json as json; use serde_json as json;
@ -14,8 +14,9 @@ use radicle::crypto::{ssh, Verified};
use radicle::explorer::ExplorerUrl; use radicle::explorer::ExplorerUrl;
use radicle::git::RefString; use radicle::git::RefString;
use radicle::identity::{RepoId, Visibility}; use radicle::identity::{RepoId, Visibility};
use radicle::node::events::UploadPack;
use radicle::node::policy::Scope; use radicle::node::policy::Scope;
use radicle::node::{Event, Handle, NodeId}; use radicle::node::{Event, Handle, NodeId, DEFAULT_SUBSCRIBE_TIMEOUT};
use radicle::prelude::Doc; use radicle::prelude::Doc;
use radicle::{profile, Node}; use radicle::{profile, Node};
@ -364,7 +365,9 @@ fn sync(
return Ok(SyncResult::NodeStopped); return Ok(SyncResult::NodeStopped);
} }
let mut spinner = term::spinner("Updating inventory.."); let mut spinner = term::spinner("Updating inventory..");
let events = node.subscribe(time::Duration::from_secs(3))?; // N.b. indefinitely subscribe to events and set a lower timeout on events
// below.
let events = node.subscribe(DEFAULT_SUBSCRIBE_TIMEOUT)?;
let sessions = node.sessions()?; let sessions = node.sessions()?;
node.update_inventory(rid)?; node.update_inventory(rid)?;
@ -392,17 +395,40 @@ fn sync(
spinner.message("Syncing.."); spinner.message("Syncing..");
let mut replicas = HashSet::new(); let mut replicas = HashSet::new();
for e in events { for e in events {
match e { match e {
Ok(Event::RefsSynced { Ok(Event::RefsSynced {
remote, rid: rid_, .. remote, rid: rid_, ..
}) if rid == rid_ => { }) if rid == rid_ => {
term::success!("Repository successfully synced to {remote}");
replicas.insert(remote); replicas.insert(remote);
// If we manage to replicate to one of our preferred seeds, we can stop waiting. // If we manage to replicate to one of our preferred seeds, we can stop waiting.
if config.preferred_seeds.iter().any(|s| s.id == remote) { if config.preferred_seeds.iter().any(|s| s.id == remote) {
break; break;
} }
} }
Ok(Event::UploadPack(UploadPack::Write {
rid: rid_,
remote,
progress,
})) if rid == rid_ => {
spinner.message(format!("Uploading {rid} to {remote} {progress}"));
}
Ok(Event::UploadPack(UploadPack::Done {
rid: rid_,
remote,
status,
})) if rid == rid_ => {
spinner.message(format!("Upload done for {rid} to {remote}: {status}"));
}
Ok(Event::UploadPack(UploadPack::Error {
rid: rid_,
remote,
err,
})) if rid == rid_ => {
spinner.message(format!("Upload error for {rid} to {remote}: {err}"));
}
Ok(_) => { Ok(_) => {
// Some other irrelevant event received. // Some other irrelevant event received.
} }