]> git.proxmox.com Git - proxmox-backup.git/blame - examples/h2client.rs
ui: add DataStoreSummary and move Statistics into it
[proxmox-backup.git] / examples / h2client.rs
CommitLineData
15d0e4a3
WB
1use std::future::Future;
2use std::pin::Pin;
3use std::task::{Context, Poll};
4
f7d4e4b5 5use anyhow::{Error};
15d0e4a3
WB
6use futures::future::TryFutureExt;
7use futures::stream::Stream;
8use tokio::net::TcpStream;
fded1f31
DM
9
10// Simple H2 client to test H2 download speed using h2server.rs
11
fded1f31
DM
12struct Process {
13 body: h2::RecvStream,
14 trailers: bool,
15 bytes: usize,
16}
17
18impl Future for Process {
15d0e4a3
WB
19 type Output = Result<usize, Error>;
20
21 fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
22 let this = self.get_mut();
fded1f31 23
fded1f31 24 loop {
15d0e4a3
WB
25 if this.trailers {
26 match futures::ready!(this.body.poll_trailers(cx)) {
27 Ok(Some(trailers)) => println!("trailers: {:?}", trailers),
28 Ok(None) => (),
29 Err(err) => return Poll::Ready(Err(Error::from(err))),
fded1f31 30 }
fded1f31 31
15d0e4a3
WB
32 println!("Received {} bytes", this.bytes);
33
34 return Poll::Ready(Ok(this.bytes));
fded1f31 35 } else {
15d0e4a3
WB
36 match futures::ready!(Pin::new(&mut this.body).poll_next(cx)) {
37 Some(Ok(chunk)) => {
db0cb9ce 38 this.body.flow_control().release_capacity(chunk.len())?;
15d0e4a3 39 this.bytes += chunk.len();
fded1f31
DM
40 // println!("GOT FRAME {}", chunk.len());
41 },
15d0e4a3 42 Some(Err(err)) => return Poll::Ready(Err(Error::from(err))),
fded1f31 43 None => {
15d0e4a3 44 this.trailers = true;
fded1f31
DM
45 },
46 }
47 }
48 }
49 }
50}
51
15d0e4a3
WB
52fn send_request(
53 mut client: h2::client::SendRequest<bytes::Bytes>,
54) -> impl Future<Output = Result<usize, Error>> {
fded1f31
DM
55
56 println!("sending request");
57
58 let request = http::Request::builder()
59 .uri("http://localhost/")
60 .body(())
61 .unwrap();
62
63 let (response, _stream) = client.send_request(request, true).unwrap();
64
65 response
66 .map_err(Error::from)
67 .and_then(|response| {
68 Process { body: response.into_body(), trailers: false, bytes: 0 }
69 })
70}
71
d973aa82
WB
72fn main() -> Result<(), Error> {
73 proxmox_backup::tools::runtime::main(run())
74}
75
76async fn run() -> Result<(), Error> {
fded1f31
DM
77
78 let start = std::time::SystemTime::now();
79
083ff3fd 80 let conn = TcpStream::connect(std::net::SocketAddr::from(([127,0,0,1], 8008)))
15d0e4a3 81 .await?;
fded1f31 82
15d0e4a3
WB
83 let (client, h2) = h2::client::Builder::new()
84 .initial_connection_window_size(1024*1024*1024)
85 .initial_window_size(1024*1024*1024)
86 .max_frame_size(4*1024*1024)
87 .handshake(conn)
88 .await?;
89
90 tokio::spawn(async move {
91 if let Err(err) = h2.await {
92 println!("GOT ERR={:?}", err);
93 }
94 });
95
96 let mut bytes = 0;
97 for _ in 0..2000 {
98 bytes += send_request(client.clone()).await?;
99 }
100
101 let elapsed = start.elapsed().unwrap();
102 let elapsed = (elapsed.as_secs() as f64) +
103 (elapsed.subsec_millis() as f64)/1000.0;
fded1f31 104
15d0e4a3 105 println!("Downloaded {} bytes, {} MB/s", bytes, (bytes as f64)/(elapsed*1024.0*1024.0));
fded1f31
DM
106
107 Ok(())
108}