Files
zeekay 1ae8d33fa5 ci: fix minrust (pin quickcheck =1.0.3) + formatting (nightly cargo fmt)
Two pre-existing CI failures (unrelated to codegen/install-zap):
- minrust 1.81: quickcheck 1.1.0 pulls rand 0.10 -> rand_core 0.10.1, whose
  Cargo.toml requires the edition2024 feature (unstable on Cargo 1.81). Pin
  quickcheck to =1.0.3 (last version on rand 0.8 / rand_core 0.6.4) — within
  MSRV, no major bump. Fresh-resolve verified: rand_core 0.10.1 leaves the graph.
- formatting: ran 'cargo +nightly fmt --all'; the CI check
  (--check --unstable-features --error-on-unformatted, nightly) now passes.
2026-06-20 02:13:18 -07:00

84 lines
2.9 KiB
Rust

use futures::AsyncReadExt as _;
use tokio::net::ToSocketAddrs;
use zap_rpc::{auto_reconnect, new_future_client, rpc_twoparty_zap, twoparty, RpcSystem};
use crate::foo_zap::foo;
pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = ::std::env::args().collect();
if args.len() != 3 {
println!("usage: {} client HOST:PORT", args[0]);
return Ok(());
}
tokio::task::LocalSet::new().run_until(try_main(args)).await
}
async fn try_main(args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
use std::net::ToSocketAddrs;
let addr = args[2]
.to_socket_addrs()?
.next()
.expect("could not parse address");
let (foo_client, set_target) =
auto_reconnect(move || Ok(new_future_client(connect(addr, false))))?;
let mut request = foo_client.identity_request();
request.get().set_x(123);
let response = request.send().promise.await?;
println!("results = {}", response.get()?.get_y());
// Tell server to crash
foo_client.crash_request().send().promise.await?;
// Client is now disconnected and should return ErrorKind::Disconnected
let mut request = foo_client.identity_request();
request.get().set_x(124);
let err = request
.send()
.promise
.await
.err()
.ok_or("Unexpected success")?;
if err.kind != zap::ErrorKind::Disconnected {
return Err(err.into());
}
// Retry failed request because auto_reconnect will make the connection again
let mut request = foo_client.identity_request();
request.get().set_x(124);
let response = request.send().promise.await?;
println!("results = {}", response.get()?.get_y());
// Tell server to crash again
foo_client.crash_request().send().promise.await?;
// Use set_target to set new connection
set_target.set_target(new_future_client(connect(addr, true)));
// Send request that uses the new target
let mut request = foo_client.identity_request();
request.get().set_x(125);
let response = request.send().promise.await?;
println!("results = {}", response.get()?.get_y());
Ok(())
}
async fn connect<A: ToSocketAddrs>(addr: A, manual: bool) -> zap::Result<foo::Client> {
let stream = tokio::net::TcpStream::connect(addr).await?;
stream.set_nodelay(true)?;
let (reader, writer) = tokio_util::compat::TokioAsyncReadCompatExt::compat(stream).split();
let network = Box::new(twoparty::VatNetwork::new(
futures::io::BufReader::new(reader),
futures::io::BufWriter::new(writer),
rpc_twoparty_zap::Side::Client,
Default::default(),
));
let mut rpc_system = RpcSystem::new(network, None);
let calculator: foo::Client = rpc_system.bootstrap(rpc_twoparty_zap::Side::Server);
tokio::task::spawn_local(rpc_system);
eprintln!("Connected (manual={manual})");
Ok(calculator)
}