A MoonBit event bus and message abstraction layer for application decoupling.
let bus = EventBus::new(name="app")
.use_middleware("audit-tag", (event, _) => {
MiddlewareContinue({ ..event, tags: append_tag(event.tags, "audit") })
})
.subscribe("audit-log", (event, _) => {
if event.payload == "" {
OutcomeFailed("empty payload")
} else {
OutcomeHandled("stored")
}
}, topic="user", tag="audit")
let event = Event::new("user.created", topic="user", payload="alice")
let (_, report) = bus.publish(event)moon run cmd/mainmoon testmoon checkmoon check
moon test
moon run cmd/main
moon fmt --check
moon infopub(all) struct BatchReport {
input_count : Int
reports : Array[DispatchReport]
remaining : EventQueue
halt_reason : BatchHaltReason
} derive(Eq, Debug)fn BatchReport::continue_with(self : BatchReport, bus : EventBus, options? : BatchOptions) -> (EventBus, BatchReport)pub(all) struct BusMetrics {
published : Int
successful_events : Int
failed_events : Int
stopped_events : Int
handler_deliveries : Int
handler_ignored : Int
handler_failures : Int
handlers : Array[HandlerMetrics]
topics : Array[TopicMetrics]
} derive(Eq, Debug)pub(all) struct DedupCache {
strategy : DedupStrategy
capacity : Int
seen : Array[SeenEvent]
next_sequence : Int
} derive(Eq, Debug)fn DedupCache::filter(self : DedupCache, events : Array[Event], accept_unkeyed? : Bool) -> (DedupCache, DedupBatch)fn DedupCache::publish_unique(self : DedupCache, bus : EventBus, events : Array[Event], accept_unkeyed? : Bool) -> (DedupCache, EventBus, UniquePublishResult)pub(all) struct DeliveryAttempt {
number : Int
event : Event
report : DispatchReport
} derive(Eq, Debug)pub(all) struct DeliveryBatch {
runs : Array[DeliveryRun]
succeeded : Int
dead_lettered : Int
dropped : Int
total_attempts : Int
} derive(Eq, Debug)pub(all) struct DeliveryRun {
original : Event
attempts : Array[DeliveryAttempt]
state : DeliveryState
dead_letter : Event?
dead_letter_report : DispatchReport?
} derive(Eq, Debug)pub(all) struct DispatchReport {
event : Event
delivered : Int
ignored : Int
failed : Int
stopped : Bool
reports : Array[HandlerReport]
} derive(Eq, Debug)fn DispatchReport::from_reports(event : Event, reports : Array[HandlerReport], stopped? : Bool) -> DispatchReportfn EventBatch::publish(self : EventBatch, bus : EventBus, options? : BatchOptions) -> (EventBus, BatchReport)pub(all) struct EventBus {
name : String
handlers : Array[Handler]
middlewares : Array[Middleware]
scheduled : Array[ScheduledEvent]
trace : Array[TraceEntry]
publish_count : Int
next_id : Int
}fn EventBus::publish_batch(self : EventBus, events : Array[Event], options? : BatchOptions) -> (EventBus, BatchReport)fn EventBus::publish_many_with_retry(self : EventBus, events : Array[Event], policy : RetryPolicy) -> (EventBus, DeliveryBatch)fn EventBus::publish_with_retry(self : EventBus, event : Event, policy : RetryPolicy) -> (EventBus, DeliveryRun)fn EventBus::subscribe(self : EventBus, name : String, topic? : String, tag? : String, min_priority? : Int, once? : Bool, callback : (Event, EventContext) -> HandlerOutcome, handler_priority? : Int) -> EventBusfn EventBus::use_middleware(self : EventBus, name : String, callback : (Event, EventContext) -> MiddlewareOutcome) -> EventBusfn EventQueue::drain(self : EventQueue, subscriptions : Array[Subscription]) -> Array[DispatchReport]pub(all) struct EventStore {
records : Array[StoredEvent]
next_sequence : Int
max_entries : Int
} derive(Eq, Debug)fn EventStore::append(self : EventStore, event : Event, source? : String, stored_tick? : Int) -> (EventStore, StoredEvent)fn EventStore::append_many(self : EventStore, events : Array[Event], source? : String, stored_tick? : Int) -> (EventStore, Array[StoredEvent])fn EventStore::replay(self : EventStore, bus : EventBus, query? : EventQuery) -> (EventBus, Array[DispatchReport])pub(all) struct Handler {
id : Int
name : String
subscription : Subscription
priority : Int
callback : (Event, EventContext) -> HandlerOutcome
}fn Handler::new(id : Int, name : String, subscription : Subscription, priority : Int, callback : (Event, EventContext) -> HandlerOutcome) -> Handlerpub(all) struct HandlerReport {
handler : String
status : HandlerStatus
note : String
} derive(Eq, Debug)fn Middleware::new(name : String, callback : (Event, EventContext) -> MiddlewareOutcome) -> Middlewarefn RetryPolicy::decide(self : RetryPolicy, event : Event, attempt : Int, reason : String) -> RetryDecisionfn RetryPolicy::new(max_attempts? : Int, dead_letter_topic? : String, retry_tag? : String) -> RetryPolicypub(all) struct RouteRule {
name : String
topic_pattern : String
required_tag : String
min_priority : Int
rule_priority : Int
terminal : Bool
active : Bool
action : RouteAction
} derive(Eq, Debug)fn RouteRule::new(name : String, topic_pattern : String, action : RouteAction, required_tag? : String, min_priority? : Int, rule_priority? : Int, terminal? : Bool) -> RouteRulefn RoutingResult::publish(self : RoutingResult, bus : EventBus) -> (EventBus, Array[DispatchReport])fn Subscription::new(id : Int, name : String, topic? : String, tag? : String, min_priority? : Int, once? : Bool) -> Subscriptionpub(all) struct TopicPattern {
raw : String
segments : Array[String]
status : TopicPatternStatus
} derive(Eq, Debug)fn TraceEntry::new(index : Int, kind : TraceKind, event_name : String, actor : String, message : String) -> TraceEntrypub(all) struct TypedEvent[A] {
name : String
topic : String
value : A
tags : Array[String]
priority : Int
correlation_id : String
encode : (A) -> String
}fn[A] TypedEvent::new(name : String, value : A, encode : (A) -> String, topic? : String, tags? : Array[String], priority? : Int, correlation_id? : String) -> TypedEvent[A]pub(all) struct UniquePublishResult {
reports : Array[DispatchReport]
accepted : Int
duplicates : Int
unkeyed : Int
} derive(Eq, Debug)pub(all) struct ValidationBatch {
results : Array[EventValidation]
valid : Int
invalid : Int
warnings : Int
errors : Int
} derive(Eq, Debug)pub(all) struct ValidationIssue {
code : String
message : String
severity : ValidationSeverity
} derive(Eq, Debug)fn validation_middleware(policy : EventValidationPolicy) -> ((Event, EventContext) -> MiddlewareOutcome)Install
Download zipA MoonBit event bus and message abstraction layer for application decoupling.