blob: c5fffdd6c45a10ca304d5883c9117dd61bd3756a [file]
use crate::actors::consumer::Consumer;
use crate::args::common::IggyBenchArgs;
use crate::benchmarks::benchmark::Benchmarkable;
use crate::rate_limiter::RateLimiter;
use async_trait::async_trait;
use iggy::error::IggyError;
use iggy::messages::PollingKind;
use iggy_bench_report::benchmark_kind::BenchmarkKind;
use iggy_bench_report::individual_metrics::BenchmarkIndividualMetrics;
use integration::test_server::ClientFactory;
use std::sync::atomic::AtomicI64;
use std::sync::Arc;
use tokio::task::JoinSet;
use tracing::info;
pub struct ConsumerBenchmark {
args: Arc<IggyBenchArgs>,
client_factory: Arc<dyn ClientFactory>,
}
impl ConsumerBenchmark {
pub fn new(args: Arc<IggyBenchArgs>, client_factory: Arc<dyn ClientFactory>) -> Self {
Self {
args,
client_factory,
}
}
}
#[async_trait]
impl Benchmarkable for ConsumerBenchmark {
async fn run(
&mut self,
) -> Result<JoinSet<Result<BenchmarkIndividualMetrics, IggyError>>, IggyError> {
self.check_streams().await?;
let consumers_count = self.args.consumers();
info!("Creating {} consumer(s)...", consumers_count);
let messages_per_batch = self.args.messages_per_batch();
let message_batches = self.args.message_batches();
let mut set = JoinSet::new();
for consumer_id in 1..=consumers_count {
let args = self.args.clone();
let client_factory = self.client_factory.clone();
info!("Executing the benchmark on consumer #{}...", consumer_id);
let args = args.clone();
let start_stream_id = args.start_stream_id();
let client_factory = client_factory.clone();
let streams_number = args.streams();
let stream_id = match self.args.kind() {
BenchmarkKind::BalancedConsumerGroup
| BenchmarkKind::BalancedProducerAndConsumerGroup => {
args.start_stream_id() + 1 + (consumer_id % streams_number)
}
_ => start_stream_id + consumer_id,
};
let warmup_time = args.warmup_time();
let polling_kind = match self.args.kind() {
BenchmarkKind::BalancedConsumerGroup
| BenchmarkKind::BalancedProducerAndConsumerGroup => PollingKind::Next,
_ => PollingKind::Offset,
};
let consumer = Consumer::new(
client_factory,
self.args.kind(),
consumer_id,
None,
stream_id,
messages_per_batch,
message_batches,
// In this test all consumers are polling 8000 messages in total, doesn't matter which one is fastest
Arc::new(AtomicI64::new(message_batches as i64)),
warmup_time,
args.sampling_time(),
args.moving_average_window(),
polling_kind,
false, // TODO: Calculate latency from timestamp in first message, it should be an argument to iggy-bench
args.rate_limit()
.map(|rl| RateLimiter::new(rl.as_bytes_u64())),
);
set.spawn(consumer.run());
}
info!("Created {} consumer(s).", consumers_count);
Ok(set)
}
fn kind(&self) -> BenchmarkKind {
self.args.kind()
}
fn args(&self) -> &IggyBenchArgs {
&self.args
}
fn client_factory(&self) -> &Arc<dyn ClientFactory> {
&self.client_factory
}
}