Deterministic causal clocks and event simulation for MoonBit
moon add cauchyQ/moonbit-causalkitmoon check --deny-warn
moon test --deny-warn
moon run cmd/mainlet local = @causal.VersionVector::new().increment("device-a").unwrap()
let remote = @causal.VersionVector::new().increment("device-b").unwrap()
assert_eq(local.compare(remote), @causal.Concurrent)pub(all) struct BatchDelivery {
buffer : CausalBuffer
released : Array[CausalOperation]
accepted_count : Int
duplicate_count : Int
} derive(Debug)fn BatchDelivery::append_to_log(self : BatchDelivery, log : OperationLog, applied_at : Int) -> OperationLogfn CausalBuffer::offer(self : CausalBuffer, operation : CausalOperation) -> (CausalBuffer, Array[CausalOperation])pub(all) struct CausalCheckpoint {
frontier : VersionVector
state : String
operation_count : Int
created_at : Int
} derive(Eq, Debug)fn CausalCheckpoint::new(frontier : VersionVector, state : String, operation_count : Int, created_at : Int) -> Result[CausalCheckpoint, CheckpointError]pub struct CausalMap {
entries : Array[CausalMapEntry]
tombstones : Array[CausalMapTombstone]
context : VersionVector
} derive(Debug)fn CausalMap::put(self : CausalMap, key : String, writer : String, value : String) -> Result[CausalMap, CausalMapError]pub(all) struct CausalOperation {
id : String
replica : String
counter : Int
prerequisites : VersionVector
payload : String
} derive(Debug)fn CausalOperation::new(id : String, replica : String, counter : Int, prerequisites : VersionVector, payload : String) -> Result[CausalOperation, BufferError]pub(all) struct CheckpointPlan {
checkpoint : CausalCheckpoint
stable_entries : Array[LoggedOperation]
replay_log : OperationLog
} derive(Debug)fn ClockDiagnosticPolicy::new(maximum_rollback : Int, maximum_forward_jump : Int) -> Result[ClockDiagnosticPolicy, ClockDiagnosticError]pub struct ClockDiagnostics {
policy : ClockDiagnosticPolicy
last_reading : Int
samples : Array[ClockSample]
rollback_count : Int
forward_jump_count : Int
} derive(Debug)fn ClockDiagnostics::new(policy : ClockDiagnosticPolicy, initial_reading : Int) -> Result[ClockDiagnostics, ClockDiagnosticError]fn ClockDiagnostics::observe(self : ClockDiagnostics, reading : Int) -> Result[ClockDiagnostics, ClockDiagnosticError]pub(all) struct ClockSample {
reading : Int
previous : Int
status : ClockReadingStatus
} derive(Eq, Debug)fn HlcTimestamp::new(physical : Int, logical : Int, node : String) -> Result[HlcTimestamp, TimestampError]pub(all) struct LastWriterWinsRegister {
value : String
writer : String
timestamp : HlcTimestamp
} derive(Eq, Debug)fn LastWriterWinsRegister::dominates(self : LastWriterWinsRegister, other : LastWriterWinsRegister) -> Boolfn LastWriterWinsRegister::merge(self : LastWriterWinsRegister, other : LastWriterWinsRegister) -> LastWriterWinsRegisterfn LastWriterWinsRegister::new(value : String, writer : String, timestamp : HlcTimestamp) -> Result[LastWriterWinsRegister, LastWriterWinsError]fn LastWriterWinsRegister::write(self : LastWriterWinsRegister, value : String, writer : String, timestamp : HlcTimestamp) -> Result[LastWriterWinsRegister, LastWriterWinsError]fn MembershipView::from_members(members : Array[ReplicaMember]) -> Result[MembershipView, MembershipError]fn MembershipView::join(self : MembershipView, replica : String) -> Result[MembershipView, MembershipError]fn MembershipView::reactivate(self : MembershipView, replica : String) -> Result[MembershipView, MembershipError]fn MembershipView::retire(self : MembershipView, replica : String) -> Result[MembershipView, MembershipError]fn MembershipView::stability_tracker(self : MembershipView) -> Result[StabilityTracker, StabilityError]fn MultiValueRegister::apply(self : MultiValueRegister, candidate : VersionedValue) -> MultiValueRegisterfn MultiValueRegister::merge(self : MultiValueRegister, other : MultiValueRegister) -> MultiValueRegisterfn MultiValueRegister::write(self : MultiValueRegister, writer : String, value : String) -> Result[MultiValueRegister, RegisterError]pub struct ObservedRemoveSet {
values : Array[ObservedValue]
removals : DotSet
context : VersionVector
} derive(Eq, Debug)fn ObservedRemoveSet::add(self : ObservedRemoveSet, replica : String, value : String) -> Result[ObservedRemoveSet, ObservedRemoveError]fn ObservedRemoveSet::compact(self : ObservedRemoveSet, stable_frontier : VersionVector) -> ObservedRemoveSetfn ObservedRemoveSet::merge(self : ObservedRemoveSet, other : ObservedRemoveSet) -> ObservedRemoveSetfn OperationLog::append(self : OperationLog, operations : Array[CausalOperation], applied_at : Int) -> OperationLogfn OperationLog::compact(self : OperationLog, frontier : VersionVector) -> (Array[LoggedOperation], OperationLog)fn OperationLog::stable_prefix(self : OperationLog, frontier : VersionVector) -> Array[LoggedOperation]pub(all) struct PendingMessage {
source : String
target : String
payload : String
sent_at : Int
deliver_at : Int
stamp : HlcTimestamp
context : VersionVector
} derive(Debug)fn PnCounter::decrement_by(self : PnCounter, replica : String, amount : Int) -> Result[PnCounter, CounterError]fn PnCounter::from_components(components : Array[CounterComponent]) -> Result[PnCounter, CounterError]fn PnCounter::increment_by(self : PnCounter, replica : String, amount : Int) -> Result[PnCounter, CounterError]pub(all) enum RegisterState {
Empty
Resolved(VersionedValue)
Conflict(Array[VersionedValue])
} derive(Debug)fn ReplicaDigest::new(replica : String, frontier : VersionVector) -> Result[ReplicaDigest, SyncError]pub(all) struct ReplicaMember {
replica : String
generation : Int
status : MemberStatus
} derive(Eq, Debug)pub(all) struct ReplicaState {
id : String
clock : HlcClock
vector : VersionVector
online : Bool
} derive(Debug)pub(all) struct ReplicationBatch {
source : String
batch_id : String
operations : Array[CausalOperation]
advertised_frontier : VersionVector
} derive(Debug)fn ReplicationBatch::new(source : String, batch_id : String, operations : Array[CausalOperation], advertised_frontier : VersionVector) -> Result[ReplicationBatch, BatchError]pub(all) struct Simulator {
time : Int
replicas : Array[ReplicaState]
pending : Array[PendingMessage]
trace : Array[TraceEvent]
} derive(Debug)fn Simulator::advance_to(self : Simulator, next_time : Int) -> Result[Array[TraceEvent], SimulatorError]fn Simulator::local_event(self : Simulator, replica_id : String, label : String) -> Result[TraceEvent, SimulatorError]fn Simulator::new(replica_ids : Array[String], start_time : Int) -> Result[Simulator, SimulatorError]fn Simulator::send(self : Simulator, source : String, target : String, payload : String, delay : Int) -> Result[TraceEvent, SimulatorError]fn Simulator::set_online(self : Simulator, replica_id : String, online : Bool) -> Result[TraceEvent, SimulatorError]fn Simulator::vector_of(self : Simulator, replica_id : String) -> Result[VersionVector, SimulatorError]pub(all) struct StabilityTracker {
replicas : Array[String]
acknowledgements : Array[ReplicaAcknowledgement]
} derive(Debug)fn StabilityTracker::observe(self : StabilityTracker, replica : String, context : VersionVector) -> Result[StabilityTracker, StabilityError]fn TraceAnalysis::relation(self : TraceAnalysis, first_sequence : Int, second_sequence : Int) -> CausalOrder?pub(all) struct TraceEvent {
sequence : Int
time : Int
replica : String
stamp : HlcTimestamp
context : VersionVector
kind : TraceKind
} derive(Debug)fn TraceQuery::between_physical_times(self : TraceQuery, from_time : Int, to_time : Int) -> Array[TraceEvent]fn VersionVector::increment(self : VersionVector, replica : String) -> Result[VersionVector, VectorError]pub(all) struct VersionedValue {
value : String
writer : String
context : VersionVector
} derive(Eq, Debug)fn plan_checkpoint(log : OperationLog, stable_frontier : VersionVector, state : String, created_at : Int) -> Result[CheckpointPlan, CheckpointError]fn validate_checkpoint_against(checkpoint : CausalCheckpoint, log : OperationLog) -> Result[Unit, CheckpointError]fn validate_replay(checkpoint : CausalCheckpoint, entries : Array[LoggedOperation]) -> Result[VersionVector, CheckpointError]Install
Download zipDeterministic causal clocks and event simulation for MoonBit