Phase 8e: cluster-ping migrates to connect_lan_first #68
+27
-3
@@ -104,6 +104,13 @@ enum Cmd {
|
|||||||
/// Peer's RPC socket. Typically gossip_port + 1.
|
/// Peer's RPC socket. Typically gossip_port + 1.
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
rpc_addr: SocketAddr,
|
rpc_addr: SocketAddr,
|
||||||
|
/// Phase 8c/8d: optional Tailscale RPC socket for
|
||||||
|
/// LAN-first-with-fallback routing. See `cluster-peer-status`.
|
||||||
|
#[arg(long)]
|
||||||
|
tailscale_addr: Option<SocketAddr>,
|
||||||
|
/// LAN probe deadline (ms) when `--tailscale-addr` is set.
|
||||||
|
#[arg(long, default_value_t = 200)]
|
||||||
|
lan_probe_ms: u64,
|
||||||
/// Payload to send. Echoed back with a "pong:" prefix.
|
/// Payload to send. Echoed back with a "pong:" prefix.
|
||||||
#[arg(long, default_value = "hello")]
|
#[arg(long, default_value = "hello")]
|
||||||
payload: String,
|
payload: String,
|
||||||
@@ -345,9 +352,11 @@ async fn main() -> Result<()> {
|
|||||||
name,
|
name,
|
||||||
peer,
|
peer,
|
||||||
rpc_addr,
|
rpc_addr,
|
||||||
|
tailscale_addr,
|
||||||
|
lan_probe_ms,
|
||||||
payload,
|
payload,
|
||||||
tls_dir,
|
tls_dir,
|
||||||
} => cmd_cluster_ping(&name, &peer, rpc_addr, &payload, tls_dir.as_deref()).await?,
|
} => cmd_cluster_ping(&name, &peer, rpc_addr, tailscale_addr, lan_probe_ms, &payload, tls_dir.as_deref()).await?,
|
||||||
Cmd::ClusterGc { evict_to_gb } => cmd_cluster_gc(&cfg, evict_to_gb).await?,
|
Cmd::ClusterGc { evict_to_gb } => cmd_cluster_gc(&cfg, evict_to_gb).await?,
|
||||||
Cmd::ClusterScrub { verbose } => cmd_cluster_scrub(&cfg, verbose).await?,
|
Cmd::ClusterScrub { verbose } => cmd_cluster_scrub(&cfg, verbose).await?,
|
||||||
Cmd::ClusterRepair {
|
Cmd::ClusterRepair {
|
||||||
@@ -1072,10 +1081,12 @@ async fn cmd_cluster_ping(
|
|||||||
name: &str,
|
name: &str,
|
||||||
peer: &str,
|
peer: &str,
|
||||||
rpc_addr: SocketAddr,
|
rpc_addr: SocketAddr,
|
||||||
|
tailscale_addr: Option<SocketAddr>,
|
||||||
|
lan_probe_ms: u64,
|
||||||
payload: &str,
|
payload: &str,
|
||||||
tls_dir: Option<&std::path::Path>,
|
tls_dir: Option<&std::path::Path>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
use cluster::transport::{ping, NodeIdentity, QuicClient};
|
use cluster::transport::{ping, ConnectRoute, NodeIdentity, QuicClient};
|
||||||
|
|
||||||
// Two identity paths:
|
// Two identity paths:
|
||||||
// 1. `--tls-dir` present → load persisted PEM. The peer must have
|
// 1. `--tls-dir` present → load persisted PEM. The peer must have
|
||||||
@@ -1093,7 +1104,20 @@ async fn cmd_cluster_ping(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let client = QuicClient::new("0.0.0.0:0".parse()?, id_self)?;
|
let client = QuicClient::new("0.0.0.0:0".parse()?, id_self)?;
|
||||||
let conn = client.connect(rpc_addr, peer).await?;
|
// Phase 8: LAN-first with optional tailnet fallback. Zero flag
|
||||||
|
// = identical to pre-8 single-addr dial.
|
||||||
|
let (conn, route) = client
|
||||||
|
.connect_lan_first(
|
||||||
|
peer,
|
||||||
|
Some(rpc_addr),
|
||||||
|
tailscale_addr,
|
||||||
|
std::time::Duration::from_millis(lan_probe_ms),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
match route {
|
||||||
|
ConnectRoute::Lan(a) => println!("route: LAN ({a})"),
|
||||||
|
ConnectRoute::Tailscale(a) => println!("route: tailnet ({a})"),
|
||||||
|
}
|
||||||
let response = ping(&conn, payload.as_bytes()).await?;
|
let response = ping(&conn, payload.as_bytes()).await?;
|
||||||
println!("→ sent: {}", payload);
|
println!("→ sent: {}", payload);
|
||||||
println!("← recv: {}", String::from_utf8_lossy(&response));
|
println!("← recv: {}", String::from_utf8_lossy(&response));
|
||||||
|
|||||||
Reference in New Issue
Block a user