bench_fetch/
bench_fetch.rs1use std::time::Instant;
4
5use partitionline::{Consumer, ConsumerConfig, TlsConfig};
6
7#[tokio::main]
8async fn main() -> partitionline::Result<()> {
9 let bootstrap = std::env::var("KAFKA_BOOTSTRAP").unwrap_or_else(|_| "127.0.0.1:9092".into());
10 let topic = std::env::var("KAFKA_TOPIC").unwrap_or_else(|_| "plbench".into());
11 let count: u64 = std::env::var("COUNT")
12 .ok()
13 .and_then(|s| s.parse().ok())
14 .unwrap_or(8_000_000);
15 let max_wait_ms = std::env::var("MAX_WAIT_MS")
16 .ok()
17 .and_then(|s| s.parse().ok())
18 .unwrap_or(100i32);
19 let max_bytes = std::env::var("MAX_BYTES")
20 .ok()
21 .and_then(|s| s.parse().ok())
22 .unwrap_or(16_777_216i32);
23 let min_bytes = std::env::var("MIN_BYTES")
24 .ok()
25 .and_then(|s| s.parse().ok())
26 .unwrap_or(1i32);
27
28 let mut cfg = ConsumerConfig::bootstrap([bootstrap]);
29 cfg.max_wait_ms = max_wait_ms;
30 cfg.max_bytes = max_bytes;
31 cfg.min_bytes = min_bytes;
32 if let Ok(ca_path) = std::env::var("TLS_CA_PEM") {
33 let mut tls = TlsConfig {
34 ca_pem: Some(tokio::fs::read(&ca_path).await.map_err(|e| {
35 partitionline::Error::protocol(format!("read TLS_CA_PEM {ca_path}: {e}"))
36 })?),
37 ..TlsConfig::default()
38 };
39 if let Ok(name) = std::env::var("TLS_SERVER_NAME") {
40 if !name.is_empty() {
41 tls.server_name = Some(name);
42 }
43 }
44 cfg.tls = Some(tls);
45 }
46 let mech = std::env::var("SASL_MECHANISM").unwrap_or_else(|_| "PLAIN".into());
47 if mech == "OAUTHBEARER" {
48 let principal = std::env::var("SASL_OAUTH_PRINCIPAL").unwrap_or_else(|_| "alice".into());
49 cfg.sasl_oauthbearer = Some(principal);
50 } else if let (Ok(user), Ok(pass)) = (
51 std::env::var("SASL_USERNAME"),
52 std::env::var("SASL_PASSWORD"),
53 ) {
54 match mech.as_str() {
55 "SCRAM-SHA-256" => cfg.sasl_scram = Some((user, pass)),
56 "SCRAM-SHA-512" => cfg.sasl_scram_sha512 = Some((user, pass)),
57 "PLAIN" => cfg.sasl_plain = Some((user, pass)),
58 other => {
59 return Err(partitionline::Error::protocol(format!(
60 "unknown SASL_MECHANISM {other}"
61 )));
62 }
63 }
64 }
65
66 let mut consumer = Consumer::new(cfg).await?;
67 consumer.assign_topic(&topic, 0).await?;
68 let assigned = consumer.assignment().len();
69 let start = Instant::now();
70 let mut got = 0u64;
71 let mut empty = 0u32;
72 while got < count {
73 let recs = consumer.fetch().await?;
74 if recs.is_empty() {
75 empty += 1;
76 if empty > 600 {
77 return Err(partitionline::Error::Timeout);
78 }
79 continue;
80 }
81 empty = 0;
82 got += recs.len() as u64;
83 }
84 let elapsed = start.elapsed().as_secs_f64();
85 let rec_s = got as f64 / elapsed.max(1e-9);
86 println!(
87 "{{\"consumed\":{got},\"elapsed_s\":{elapsed:.6},\"consumed_rec_s\":{rec_s:.3},\"partitions\":{assigned},\"max_wait_ms\":{max_wait_ms},\"max_bytes\":{max_bytes}}}"
88 );
89 Ok(())
90}