Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]
resolver = "2"
members = [".", "actors", "console", "macros"]
members = [".", "actors", "bombay-core", "console", "macros"]

[workspace.package]
edition = "2024"
Expand Down
30 changes: 30 additions & 0 deletions bombay-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[package]
name = "bombay-core"
version = "0.1.0"
edition.workspace = true
license.workspace = true
authors.workspace = true
repository.workspace = true
description = "Bombay runtime core — the rebuilt local actor spine (mailbox, message, reply, actor loop). Transport- and domain-agnostic."
publish = false

[dependencies]
tokio = { workspace = true, features = ["sync", "rt", "macros", "time"] }

[dev-dependencies]
tokio = { workspace = true, features = [
"rt",
"rt-multi-thread",
"macros",
"sync",
"time",
] }
proptest = { workspace = true }
criterion = { version = "0.8", features = ["async_tokio"] }

[[bench]]
name = "mailbox"
harness = false

[lints]
workspace = true
73 changes: 73 additions & 0 deletions bombay-core/benches/mailbox.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//! Criterion benches for the mailbox hot path.
//!
//! The card's premise — a zero-box `tell` is cheaper than kameo's
//! `Box<dyn DynMessage>` enqueue — is un-templated: no framework ships this
//! shape, so we *measure* rather than assume (#112). These numbers are the
//! baseline the later two-tier wiring (#114/#118) is compared against.

use std::num::NonZeroUsize;

use bombay_core::mailbox::{Capacity, Mailboxed, Signal, bounded};
use criterion::{BatchSize, Criterion, black_box, criterion_group, criterion_main};

struct Bench;
impl Mailboxed for Bench {
type Msg = u64;
}

fn cap(n: usize) -> Capacity {
Capacity::new(NonZeroUsize::new(n).expect("nonzero")).expect("within max")
}

/// Pure enqueue cost: how long to `try_send` 1_000 messages into a mailbox with
/// spare capacity. `iter_batched_ref` keeps the `bounded()` setup out of the
/// measured region, and the fresh mailbox per batch never fills, so this isolates
/// the move-into-slot cost of a `tell`.
fn enqueue(c: &mut Criterion) {
c.bench_function("tell_try_send_1k_u64", |b| {
b.iter_batched_ref(
|| bounded::<Bench>(cap(1024)),
|(tx, _rx)| {
for i in 0..1000u64 {
tx.try_send(Signal::Message(black_box(i)))
.expect("capacity available");
}
},
BatchSize::SmallInput,
);
});
}

/// End-to-end throughput: 1_000 `send`s and 1_000 `recv`s across a producer task
/// and the consumer, on a current-thread runtime.
fn roundtrip(c: &mut Criterion) {
let rt = tokio::runtime::Builder::new_current_thread()
.build()
.expect("current-thread runtime");

c.bench_function("send_recv_roundtrip_1k_u64", |b| {
b.iter(|| {
rt.block_on(async {
let (tx, mut rx) = bounded::<Bench>(cap(1024));
let producer = tokio::spawn(async move {
for i in 0..1000u64 {
tx.send(Signal::Message(black_box(i))).await.expect("send");
}
});

let mut received = 0u32;
while received < 1000 {
let Some(Signal::Message(_)) = rx.recv().await else {
break;
};
received += 1;
}
producer.await.expect("producer");
black_box(received)
});
});
});
}

criterion_group!(benches, enqueue, roundtrip);
criterion_main!(benches);
10 changes: 10 additions & 0 deletions bombay-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//! Bombay runtime core — the rebuilt local actor spine.
//!
//! Built card-by-card (M1 epic #122) with kameo as a reference oracle, held to
//! the god-level clippy bar from line one. Transport- and domain-agnostic: the
//! Zenoh remote tier and the nexus aggregate-runner sit on top of this.
//!
//! Nothing here is public API yet — the spine is assembled part-by-part and the
//! surface is settled once the whole core lands (#112–#121).

pub mod mailbox;
Loading
Loading