1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-27 12:23:46 +03:00

add simple ping/pong cli rpc

This commit is contained in:
Wez Furlong 2019-03-13 20:35:44 -07:00
parent d3b3027cfc
commit bd1b66e758
4 changed files with 106 additions and 22 deletions

View File

@ -109,9 +109,16 @@ enum SubCommand {
#[structopt(name = "start", about = "Start a front-end")]
#[structopt(raw(setting = "structopt::clap::AppSettings::ColoredHelp"))]
Start(StartCommand),
#[structopt(name = "cli", about = "Interact with mux server")]
#[structopt(raw(setting = "structopt::clap::AppSettings::ColoredHelp"))]
Cli(CliCommand),
}
fn run_terminal_gui(config: Arc<config::Config>, opts: StartCommand) -> Result<(), Error> {
#[derive(Debug, StructOpt)]
struct CliCommand {}
fn run_terminal_gui(config: Arc<config::Config>, opts: &StartCommand) -> Result<(), Error> {
let font_system = opts.font_system.unwrap_or(config.font_system);
font_system.set_default();
@ -140,10 +147,18 @@ fn main() -> Result<(), Error> {
} else {
config::Config::load()?
});
println!("Using configuration: {:#?}\nopts: {:#?}", config, opts);
match opts.cmd {
SubCommand::Start(start) => run_terminal_gui(config, start),
match &opts.cmd {
SubCommand::Start(start) => {
println!("Using configuration: {:#?}\nopts: {:#?}", config, opts);
run_terminal_gui(config, start)
}
SubCommand::Cli(_) => {
use crate::server::client::Client;
let mut client = Client::new(&config)?;
eprintln!("ping: {:?}", client.ping()?);
Ok(())
}
}
}

View File

@ -1 +1,44 @@
pub struct Client {}
use crate::config::Config;
use crate::server::codec::*;
use crate::server::UnixStream;
use failure::{err_msg, Error};
use std::path::Path;
use std::sync::Arc;
pub struct Client {
stream: UnixStream,
serial: u64,
}
impl Client {
pub fn new(config: &Arc<Config>) -> Result<Self, Error> {
let sock_path = Path::new(
config
.mux_server_unix_domain_socket_path
.as_ref()
.ok_or_else(|| err_msg("no mux_server_unix_domain_socket_path"))?,
);
eprintln!("connect to {}", sock_path.display());
let stream = UnixStream::connect(sock_path)?;
Ok(Self { stream, serial: 0 })
}
pub fn ping(&mut self) -> Result<(), Error> {
let ping_serial = self.serial;
self.serial += 1;
Pdu::Ping(Ping {
serial: ping_serial,
})
.encode(&mut self.stream)?;
let pdu = Pdu::decode(&mut self.stream)?;
match pdu {
Pdu::Pong(Pong { serial }) if serial == ping_serial => Ok(()),
Pdu::Pong(Pong { serial }) => bail!(
"expected pong with serial {} but got {}",
ping_serial,
serial
),
_ => bail!("expected Pong response, got {:?}", pdu),
}
}
}

View File

@ -58,9 +58,13 @@ pub fn decode_raw<R: std::io::Read>(mut r: R) -> Result<(u64, Vec<u8>), std::io:
}
#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct Ping {}
pub struct Ping {
pub serial: u64,
}
#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct Pong {}
pub struct Pong {
pub serial: u64,
}
macro_rules! pdu {
($( $name:ident:$vers:expr),* $(,)?) => {
@ -140,9 +144,13 @@ mod test {
#[test]
fn test_pdu_ping() {
let mut encoded = Vec::new();
Pdu::Ping(Ping {}).encode(&mut encoded).unwrap();
assert_eq!(&encoded, b"\x01\x01");
assert_eq!(Pdu::Ping(Ping {}), Pdu::decode(encoded.as_slice()).unwrap());
Pdu::Ping(Ping { serial: 1 }).encode(&mut encoded).unwrap();
// FIXME: bincode is a bit long for this
assert_eq!(&encoded, &[9, 1, 1, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(
Pdu::Ping(Ping { serial: 1 }),
Pdu::decode(encoded.as_slice()).unwrap()
);
}
#[test]
@ -150,19 +158,25 @@ mod test {
let mut encoded = Vec::new();
{
let mut encoder = base91::Base91Encoder::new(&mut encoded);
Pdu::Ping(Ping {}).encode(&mut encoder).unwrap();
Pdu::Ping(Ping { serial: 1 }).encode(&mut encoder).unwrap();
}
assert_eq!(&encoded, b";CA");
assert_eq!(&encoded, &[94, 67, 73, 65, 65, 65, 65, 65, 65, 65, 65, 65]);
let decoded = base91::decode(&encoded);
assert_eq!(Pdu::Ping(Ping {}), Pdu::decode(decoded.as_slice()).unwrap());
assert_eq!(
Pdu::Ping(Ping { serial: 1 }),
Pdu::decode(decoded.as_slice()).unwrap()
);
}
#[test]
fn test_pdu_pong() {
let mut encoded = Vec::new();
Pdu::Pong(Pong {}).encode(&mut encoded).unwrap();
assert_eq!(&encoded, b"\x01\x02");
assert_eq!(Pdu::Pong(Pong {}), Pdu::decode(encoded.as_slice()).unwrap());
Pdu::Pong(Pong { serial: 1 }).encode(&mut encoded).unwrap();
assert_eq!(&encoded, &[9, 2, 1, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(
Pdu::Pong(Pong { serial: 1 }),
Pdu::decode(encoded.as_slice()).unwrap()
);
}
#[test]

View File

@ -1,21 +1,17 @@
use crate::config::Config;
use crate::server::codec::*;
use crate::server::{UnixListener, UnixStream};
use failure::{err_msg, Error};
#[cfg(unix)]
use libc::{mode_t, umask};
use promise::Executor;
use std::fs::{remove_file, DirBuilder};
use std::io::{Read, Write};
#[cfg(unix)]
use std::os::unix::fs::{DirBuilderExt, PermissionsExt};
use std::path::Path;
use std::sync::Arc;
use std::thread;
pub trait SocketLike: Read + Write + Send {}
impl SocketLike for UnixStream {}
pub struct Listener {
acceptor: UnixListener,
executor: Box<Executor>,
@ -53,7 +49,23 @@ impl ClientSession {
Self { stream, executor }
}
fn run(&mut self) {}
fn process(&mut self) -> Result<(), Error> {
loop {
let pdu = Pdu::decode(&mut self.stream)?;
eprintln!("got pdu {:?} from client", pdu);
match pdu {
Pdu::Ping(Ping { serial }) => {
Pdu::Pong(Pong { serial }).encode(&mut self.stream)?;
}
Pdu::Pong { .. } | Pdu::Invalid { .. } => {}
}
}
}
fn run(&mut self) {
self.process().ok();
}
}
/// Unfortunately, novice unix users can sometimes be running