#![cfg(feature = "bench")]
use std::sync::Arc;
use myko::{
bench_entities::{
BenchCompoundChild, BenchCompoundChildQuery, BenchParentAId, BenchParentBId,
GetBenchCompoundChildsByQuery,
},
entities::{
client::{Client, ClientQuery, GetClientsByQuery},
server::ServerId,
},
query::{IdFilter, query_runtime_metrics_by_id},
server::{HandlerRegistry, MykoServerContext, RelationshipManager, persister::PersisterRouter},
store::StoreRegistry,
wire::{MEvent, MEventType},
};
use uuid::Uuid;
fn scheduler_test_serial() -> std::sync::MutexGuard<'static, ()> {
static LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
LOCK.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
}
fn make_ctx() -> MykoServerContext {
MykoServerContext::new(
Uuid::new_v4(),
Arc::new(StoreRegistry::new()),
Arc::new(HandlerRegistry::new()),
Arc::new(RelationshipManager::new()),
Arc::new(PersisterRouter::default()),
Arc::new(myko::search::SearchIndex::new()),
myko::server::MykoServerRuntime {
peer_clients: Arc::new(dashmap::DashMap::new()),
event_sink: None,
history_replay: None,
},
)
}
fn insert_client(ctx: &MykoServerContext, id: &str, server_id: &str) {
let client = Client {
id: id.into(),
server_id: ServerId::from(Arc::<str>::from(server_id)),
address: None,
windback: None,
};
let event = MEvent::from_item(&client, MEventType::SET, &format!("tx-{id}"));
assert!(ctx.apply_event_batch(vec![event]).is_ok());
}
fn insert_compound_child(
ctx: &MykoServerContext,
id: &str,
parent_a: &str,
parent_b: &str,
value: i64,
) {
let child = BenchCompoundChild {
id: id.into(),
parent_a_id: BenchParentAId::from(Arc::<str>::from(parent_a)),
parent_b_id: BenchParentBId::from(Arc::<str>::from(parent_b)),
value,
};
let event = MEvent::from_item(&child, MEventType::SET, &format!("tx-{id}"));
assert!(ctx.apply_event_batch(vec![event]).is_ok());
}
fn request(ctx: &MykoServerContext, tx: &str) -> Arc<myko::request::RequestContext> {
Arc::new(myko::request::RequestContext::from_client(
Arc::from(tx),
Arc::from("client-1"),
ctx.host_id,
))
}
#[test]
fn compound_two_belongs_to_in_filter_returns_exact_union() {
let _serial = scheduler_test_serial();
let ctx = make_ctx();
insert_compound_child(&ctx, "c1", "A1", "B1", 1); insert_compound_child(&ctx, "c2", "A2", "B2", 2); insert_compound_child(&ctx, "c3", "A1", "B3", 3); insert_compound_child(&ctx, "c4", "A3", "B1", 4);
let filter = BenchCompoundChildQuery {
parent_a_id: Some(IdFilter::In(vec![
BenchParentAId::from(Arc::<str>::from("A1")),
BenchParentAId::from(Arc::<str>::from("A2")),
])),
parent_b_id: Some(IdFilter::In(vec![
BenchParentBId::from(Arc::<str>::from("B1")),
BenchParentBId::from(Arc::<str>::from("B2")),
])),
..Default::default()
};
let cell = ctx.query_map(GetBenchCompoundChildsByQuery(filter), request(&ctx, "tx-1"));
assert_eq!(
cell.snapshot().len(),
2,
"must return exactly c1 and c2 — the only items matching one of the 4 compound keys"
);
}
#[test]
fn writes_to_non_matching_belongs_to_buckets_do_not_change_the_result() {
let _serial = scheduler_test_serial();
let ctx = make_ctx();
insert_client(&ctx, "c1", "server-A");
let filter = ClientQuery {
server_id: Some(IdFilter::In(vec![ServerId::from(Arc::<str>::from(
"server-A",
))])),
..Default::default()
};
let cell = ctx.query_map(GetClientsByQuery(filter), request(&ctx, "tx-1"));
assert_eq!(cell.snapshot().len(), 1);
for i in 0..10 {
insert_client(&ctx, &format!("other-{i}"), &format!("server-{i}"));
}
assert_eq!(
cell.snapshot().len(),
1,
"10 writes to non-matching server buckets must not affect the result"
);
}
#[test]
fn item_moving_out_of_the_in_set_disappears() {
let _serial = scheduler_test_serial();
let ctx = make_ctx();
insert_client(&ctx, "c1", "server-A");
let filter = ClientQuery {
server_id: Some(IdFilter::In(vec![ServerId::from(Arc::<str>::from(
"server-A",
))])),
..Default::default()
};
let cell = ctx.query_map(GetClientsByQuery(filter), request(&ctx, "tx-1"));
assert_eq!(cell.snapshot().len(), 1);
insert_client(&ctx, "c1", "server-Z");
assert_eq!(
cell.snapshot().len(),
0,
"an item whose fk mutates OUT of the In set must be removed from the result"
);
}
#[test]
fn item_moving_into_the_in_set_appears() {
let _serial = scheduler_test_serial();
let ctx = make_ctx();
insert_client(&ctx, "c1", "server-Z");
let filter = ClientQuery {
server_id: Some(IdFilter::In(vec![ServerId::from(Arc::<str>::from(
"server-A",
))])),
..Default::default()
};
let cell = ctx.query_map(GetClientsByQuery(filter), request(&ctx, "tx-1"));
assert_eq!(cell.snapshot().len(), 0);
insert_client(&ctx, "c1", "server-A");
assert_eq!(
cell.snapshot().len(),
1,
"an item whose fk mutates INTO the In set must appear in the result"
);
}
#[test]
fn permuted_in_filters_share_one_query_cell() {
let _serial = scheduler_test_serial();
let ctx = make_ctx();
insert_client(&ctx, "c1", "server-A");
insert_client(&ctx, "c2", "server-B");
let before = query_runtime_metrics_by_id(usize::MAX)
.into_iter()
.find(|m| m.query_id.as_ref() == "GetClientsByQuery")
.map_or(0, |m| m.cell_factories_created);
let filter_a = ClientQuery {
server_id: Some(IdFilter::In(vec![
ServerId::from(Arc::<str>::from("server-A")),
ServerId::from(Arc::<str>::from("server-B")),
])),
..Default::default()
};
let filter_b = ClientQuery {
server_id: Some(IdFilter::In(vec![
ServerId::from(Arc::<str>::from("server-B")),
ServerId::from(Arc::<str>::from("server-A")),
ServerId::from(Arc::<str>::from("server-B")),
])),
..Default::default()
};
let cell_a = ctx.query_map(GetClientsByQuery(filter_a), request(&ctx, "tx-a"));
let cell_b = ctx.query_map(GetClientsByQuery(filter_b), request(&ctx, "tx-b"));
assert_eq!(cell_a.snapshot().len(), 2);
assert_eq!(cell_b.snapshot().len(), 2);
let after = query_runtime_metrics_by_id(usize::MAX)
.into_iter()
.find(|m| m.query_id.as_ref() == "GetClientsByQuery")
.map_or(0, |m| m.cell_factories_created);
assert_eq!(
after.saturating_sub(before),
1,
"two equivalent (canonicalization-wise) advanced queries from different call sites \
must share one query cell — exactly one cell_factory invocation, not two"
);
}
#[test]
fn distinct_filters_do_not_share_a_query_cell() {
let _serial = scheduler_test_serial();
let ctx = make_ctx();
insert_client(&ctx, "c1", "server-A");
insert_client(&ctx, "c2", "server-B");
let before = query_runtime_metrics_by_id(usize::MAX)
.into_iter()
.find(|m| m.query_id.as_ref() == "GetClientsByQuery")
.map_or(0, |m| m.cell_factories_created);
let filter_a = ClientQuery {
server_id: Some(IdFilter::Eq(ServerId::from(Arc::<str>::from("server-A")))),
..Default::default()
};
let filter_c = ClientQuery {
server_id: Some(IdFilter::Eq(ServerId::from(Arc::<str>::from("server-C")))),
..Default::default()
};
let _cell_a = ctx.query_map(GetClientsByQuery(filter_a), request(&ctx, "tx-a"));
let _cell_c = ctx.query_map(GetClientsByQuery(filter_c), request(&ctx, "tx-c"));
let after = query_runtime_metrics_by_id(usize::MAX)
.into_iter()
.find(|m| m.query_id.as_ref() == "GetClientsByQuery")
.map_or(0, |m| m.cell_factories_created);
assert_eq!(
after.saturating_sub(before),
2,
"genuinely distinct filters must NOT collapse onto one cache entry"
);
}