cli: Add `--timeout` and `--count` to `node events`

This commit is contained in:
cloudhead 2023-08-03 11:39:33 +02:00
parent 2d79eecd66
commit c30f137bb1
No known key found for this signature in database
3 changed files with 49 additions and 17 deletions

View File

@ -32,28 +32,33 @@ Usage
rad node connect <nid>@<addr> [<option>...] rad node connect <nid>@<addr> [<option>...]
rad node routing [--rid <rid>] [--nid <nid>] [--json] [<option>...] rad node routing [--rid <rid>] [--nid <nid>] [--json] [<option>...]
rad node tracking [--repos | --nodes] [<option>...] rad node tracking [--repos | --nodes] [<option>...]
rad node events [<option>...] rad node events [--timeout <secs>] [-n <count>] [<option>...]
For `<node-option>` see `radicle-node --help`. For `<node-option>` see `radicle-node --help`.
Start options Start options
--foreground Start the node in the foreground --foreground Start the node in the foreground
Routing options Routing options
--rid <rid> Show the routing table entries for the given RID --rid <rid> Show the routing table entries for the given RID
--nid <nid> Show the routing table entries for the given NID --nid <nid> Show the routing table entries for the given NID
--json Output the routing table as json --json Output the routing table as json
Tracking options Tracking options
--repos Show the tracked repositories table --repos Show the tracked repositories table
--nodes Show the tracked nodes table --nodes Show the tracked nodes table
Events options
--timeout <secs> How long to wait to receive an event before giving up
--count, -n <count> Exit after <count> events
General options General options
--help Print help --help Print help
"#, "#,
}; };
@ -65,7 +70,10 @@ pub enum Operation {
Connect { Connect {
addr: PeerAddr<NodeId, Address>, addr: PeerAddr<NodeId, Address>,
}, },
Events, Events {
timeout: time::Duration,
count: usize,
},
Routing { Routing {
json: bool, json: bool,
rid: Option<Id>, rid: Option<Id>,
@ -119,6 +127,8 @@ impl Args for Options {
let mut json: bool = false; let mut json: bool = false;
let mut addr: Option<PeerAddr<NodeId, Address>> = None; let mut addr: Option<PeerAddr<NodeId, Address>> = None;
let mut lines: usize = 10; let mut lines: usize = 10;
let mut count: usize = usize::MAX;
let mut timeout = time::Duration::MAX;
while let Some(arg) = parser.next()? { while let Some(arg) = parser.next()? {
match arg { match arg {
@ -149,6 +159,14 @@ impl Args for Options {
nid = term::args::nid(&val).ok(); nid = term::args::nid(&val).ok();
} }
Long("json") if matches!(op, Some(OperationName::Routing)) => json = true, Long("json") if matches!(op, Some(OperationName::Routing)) => json = true,
Long("timeout") if matches!(op, Some(OperationName::Events)) => {
let val = parser.value()?;
timeout = term::args::seconds(&val)?;
}
Long("count") | Short('n') if matches!(op, Some(OperationName::Events)) => {
let val = parser.value()?;
count = term::args::number(&val)?;
}
Long("repos") if matches!(op, Some(OperationName::Tracking)) => { Long("repos") if matches!(op, Some(OperationName::Tracking)) => {
tracking_mode = TrackingMode::Repos tracking_mode = TrackingMode::Repos
} }
@ -174,7 +192,7 @@ impl Args for Options {
anyhow!("an address of the form `<nid>@<host>:<port>` must be provided") anyhow!("an address of the form `<nid>@<host>:<port>` must be provided")
})?, })?,
}, },
OperationName::Events => Operation::Events, OperationName::Events => Operation::Events { timeout, count },
OperationName::Routing => Operation::Routing { rid, nid, json }, OperationName::Routing => Operation::Routing { rid, nid, json },
OperationName::Logs => Operation::Logs { lines }, OperationName::Logs => Operation::Logs { lines },
OperationName::Start => Operation::Start { OperationName::Start => Operation::Start {
@ -197,8 +215,8 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
match options.op { match options.op {
Operation::Connect { addr } => control::connect(&mut node, addr.id, addr.addr)?, Operation::Connect { addr } => control::connect(&mut node, addr.id, addr.addr)?,
Operation::Events => { Operation::Events { timeout, count } => {
events::run(node)?; events::run(node, count, timeout)?;
} }
Operation::Routing { rid, nid, json } => { Operation::Routing { rid, nid, json } => {
let store = let store =

View File

@ -2,12 +2,18 @@ use std::time;
use radicle::node::Handle; use radicle::node::Handle;
pub fn run(node: impl Handle) -> anyhow::Result<()> { pub fn run(node: impl Handle, count: usize, timeout: time::Duration) -> anyhow::Result<()> {
let events = node.subscribe(time::Duration::MAX)?; let events = node.subscribe(timeout)?;
for event in events { for (i, event) in events.enumerate() {
let event = event?; let event = event?;
let json_string = serde_json::to_string(&event)?; let obj = serde_json::to_string(&event)?;
println!("{json_string}");
println!("{obj}");
// Only output up to `count` events.
if i + 1 >= count {
break;
}
} }
Ok(()) Ok(())

View File

@ -1,5 +1,6 @@
use std::ffi::OsString; use std::ffi::OsString;
use std::str::FromStr; use std::str::FromStr;
use std::time;
use anyhow::anyhow; use anyhow::anyhow;
@ -132,6 +133,13 @@ pub fn number(val: &OsString) -> anyhow::Result<usize> {
usize::from_str(&val).map_err(|_| anyhow!("invalid number '{}'", val)) usize::from_str(&val).map_err(|_| anyhow!("invalid number '{}'", val))
} }
pub fn seconds(val: &OsString) -> anyhow::Result<time::Duration> {
let val = val.to_string_lossy();
let secs = u64::from_str(&val).map_err(|_| anyhow!("invalid number of seconds '{}'", val))?;
Ok(time::Duration::from_secs(secs))
}
pub fn string(val: &OsString) -> String { pub fn string(val: &OsString) -> String {
val.to_string_lossy().to_string() val.to_string_lossy().to_string()
} }