#![deny(missing_docs)]
#![deny(rust_2018_idioms)]
mod jobs;
mod kv;
mod pubsub;
mod request_reply;
pub use jobs::MemoryJobQueue;
pub use kv::MemoryKv;
pub use pubsub::MemoryPubsub;
pub use request_reply::MemoryRequestReply;
use klieo_core::{BusHandles, JobQueue, KvStore, Pubsub, RequestReply};
use std::sync::Arc;
pub struct MemoryBus {
pub pubsub: Arc<dyn Pubsub>,
pub request_reply: Arc<dyn RequestReply>,
pub kv: Arc<dyn KvStore>,
pub jobs: Arc<dyn JobQueue>,
}
impl MemoryBus {
pub fn new() -> Self {
let pubsub_concrete = Arc::new(MemoryPubsub::new());
let kv_concrete = Arc::new(MemoryKv::new());
let rr_concrete = Arc::new(MemoryRequestReply::new(pubsub_concrete.clone()));
let jobs_concrete = Arc::new(MemoryJobQueue::new(
pubsub_concrete.clone(),
kv_concrete.clone(),
));
Self {
pubsub: pubsub_concrete,
request_reply: rr_concrete,
kv: kv_concrete,
jobs: jobs_concrete,
}
}
}
impl Default for MemoryBus {
fn default() -> Self {
Self::new()
}
}
impl From<MemoryBus> for BusHandles {
fn from(value: MemoryBus) -> Self {
BusHandles::new(value.pubsub, value.kv, value.request_reply, value.jobs)
}
}
#[cfg(test)]
mod lib_tests {
use super::*;
use bytes::Bytes;
use klieo_core::bus::{Headers, Job};
use klieo_core::ids::DurableName;
use std::time::Duration;
use tokio_stream::StreamExt;
#[tokio::test]
async fn memory_bus_wires_all_four() {
let bus = MemoryBus::new();
bus.kv
.put("b", "k", Bytes::from_static(b"v"))
.await
.unwrap();
let entry = bus.kv.get("b", "k").await.unwrap().unwrap();
assert_eq!(entry.value, Bytes::from_static(b"v"));
let mut sub = bus
.pubsub
.subscribe("s", DurableName::new("d"))
.await
.unwrap();
bus.pubsub
.publish("s", Bytes::from_static(b"hi"), Headers::new())
.await
.unwrap();
let msg = sub.next().await.unwrap().unwrap();
assert_eq!(msg.payload, Bytes::from_static(b"hi"));
let err = bus
.request_reply
.request("svc", Bytes::from_static(b"x"), Duration::from_millis(20))
.await
.unwrap_err();
assert!(matches!(err, klieo_core::BusError::Timeout));
let id = bus
.jobs
.enqueue("q", Job::new(Bytes::from_static(b"j")))
.await
.unwrap();
let claimed = bus
.jobs
.claim("q", "w", Duration::from_secs(1))
.await
.unwrap()
.unwrap();
assert_eq!(claimed.id, id);
}
#[tokio::test]
async fn bus_handles_from_memory_bus_preserves_handles() {
let bus = MemoryBus::new();
let ps = Arc::as_ptr(&bus.pubsub);
let kv = Arc::as_ptr(&bus.kv);
let rr = Arc::as_ptr(&bus.request_reply);
let jq = Arc::as_ptr(&bus.jobs);
let handles: BusHandles = bus.into();
assert!(std::ptr::addr_eq(Arc::as_ptr(&handles.pubsub), ps));
assert!(std::ptr::addr_eq(Arc::as_ptr(&handles.kv), kv));
assert!(std::ptr::addr_eq(Arc::as_ptr(&handles.request_reply), rr));
assert!(std::ptr::addr_eq(Arc::as_ptr(&handles.jobs), jq));
}
}