#![allow(
missing_docs,
unused_qualifications,
unreachable_pub,
clippy::must_use_candidate,
clippy::needless_pass_by_value
)]
mod common;
use std::hint::black_box;
use common::{Latch, MESSAGES, Order, Ready, Started};
use divan::Bencher;
use divan::counter::ItemsCount;
use ruststream::memory::prelude::*;
use serde::Serialize;
fn main() {
divan::main();
}
#[derive(Debug, Serialize, Outgoing)]
#[outgoing(name = "confirmations")]
struct Confirmation {
id: u64,
}
#[subscriber("orders")]
async fn consume(order: &Order, ctx: &mut Context<'_, (), Latch>) -> HandlerOutcome {
black_box((order.id, order.quantity));
ctx.state().arrived();
HandlerOutcome::ack()
}
#[subscriber("orders", workers(4))]
async fn pooled(order: &Order, ctx: &mut Context<'_, (), Latch>) -> HandlerOutcome {
black_box((order.id, order.quantity));
ctx.state().arrived();
HandlerOutcome::ack()
}
#[subscriber("orders", threads(4))]
async fn threaded(order: &Order, ctx: &mut Context<'_, (), Latch>) -> HandlerOutcome {
black_box((order.id, order.quantity));
ctx.state().arrived();
HandlerOutcome::ack()
}
#[subscriber("orders", threads(1))]
async fn threaded_one(order: &Order, ctx: &mut Context<'_, (), Latch>) -> HandlerOutcome {
black_box((order.id, order.quantity));
ctx.state().arrived();
HandlerOutcome::ack()
}
#[subscriber("orders", reply)]
async fn confirm(order: &Order, ctx: &mut Context<'_, (), Latch>) -> Confirmation {
ctx.state().arrived();
Confirmation {
id: black_box(order.id),
}
}
fn consuming() -> Ready {
common::pending(MESSAGES, 0, |b| {
b.include(consume);
})
.ready()
}
fn replying() -> Ready {
common::pending(MESSAGES, 0, |b| {
b.include(confirm);
})
.ready()
}
fn consuming_across_threads() -> Started {
common::pending_on(common::worker_runtime(), MESSAGES, 0, |b| {
b.include(consume);
})
.started()
}
fn pooled_across_threads() -> Started {
common::pending_on(common::worker_runtime(), MESSAGES, 0, |b| {
b.include(pooled);
})
.started()
}
fn threaded_across_threads() -> Started {
common::pending_on(common::worker_runtime(), MESSAGES, 0, |b| {
b.include(threaded);
})
.started()
}
fn threaded_one_across_threads() -> Started {
common::pending_on(common::worker_runtime(), MESSAGES, 0, |b| {
b.include(threaded_one);
})
.started()
}
#[divan::bench]
fn consume_json(bencher: Bencher) {
bencher
.counter(ItemsCount::new(MESSAGES))
.with_inputs(consuming)
.bench_local_values(|ready| ready.runtime.block_on(ready.latch.drained()));
}
#[divan::bench]
fn reply(bencher: Bencher) {
bencher
.counter(ItemsCount::new(MESSAGES))
.with_inputs(replying)
.bench_local_values(|ready| ready.runtime.block_on(ready.latch.drained()));
}
#[divan::bench]
fn consume_json_across_threads(bencher: Bencher) {
bencher
.counter(ItemsCount::new(MESSAGES))
.with_inputs(consuming_across_threads)
.bench_local_values(|started| started.publish_and_drain());
}
#[divan::bench]
fn pool_across_threads(bencher: Bencher) {
bencher
.counter(ItemsCount::new(MESSAGES))
.with_inputs(pooled_across_threads)
.bench_local_values(|started| started.publish_and_drain());
}
#[divan::bench]
fn threads_across_threads(bencher: Bencher) {
bencher
.counter(ItemsCount::new(MESSAGES))
.with_inputs(threaded_across_threads)
.bench_local_values(|started| started.publish_and_drain());
}
#[divan::bench]
fn one_thread_across_threads(bencher: Bencher) {
bencher
.counter(ItemsCount::new(MESSAGES))
.with_inputs(threaded_one_across_threads)
.bench_local_values(|started| started.publish_and_drain());
}