Sign in

    relay

    Distributed message queue with V3 reliability and Valkey support

    Download zip
    Author
    Version
    0.4.0
    License
    Apache-2.0
    Last updated
    4 months ago
    Downloads
    133

    Metalymph/relay does not have a README file

    QueueError

    pub suberror QueueError {
    OperationFailed(String)
    } derive(ToJson,
    Debug
    )

    QueueError represents errors related to queue lifecycle and operations.

    AdminReport

    pub struct AdminReport {
    status : SystemStatus
    requires_attention : Bool
    queue_size : Int?
    dlq_size : Int?
    pending_count : Int64?
    summary : String
    }

    AdminReport represents a high-level operational report.

    AdminReport::has_incidents

    fn AdminReport::has_incidents(self : AdminReport) -> Bool

    has_incidents returns true when operator attention is required.

    AdminReport::is_healthy

    fn AdminReport::is_healthy(self : AdminReport) -> Bool

    is_healthy returns true when the report status is healthy.

    BackendCapabilities

    pub struct BackendCapabilities {
    supports_ack : Bool
    supports_dlq : Bool
    supports_pending : Bool
    supports_consumer_groups : Bool
    supports_health_checks : Bool
    supports_telemetry : Bool
    }

    BackendCapabilities describes the features supported by a queue backend.

    BackendCapabilities::in_memory

    BackendCapabilities::redis_lists

    BackendCapabilities::redis_streams

    BackendHealth

    pub struct BackendHealth {
    healthy : Bool
    message : String?
    }

    Dashboard

    pub struct Dashboard[T] {
    queue : RelayQueue[T]
    backend : InMemoryBackend[T]
    }

    Dashboard provides a visual representation of the RelayQueue state.

    Dashboard::new

    fn[T] Dashboard::new(queue : RelayQueue[T], backend : InMemoryBackend[T]) -> Dashboard[T]

    new creates a new dashboard for the provided queue and backend.

    Dashboard::render

    fn[T] Dashboard::render(self : Dashboard[T]) -> Unit

    render prints an ANSI color-coded snapshot of the current queue state.

    Dashboard::start_auto_render

    fn[T] Dashboard::start_auto_render(self : Dashboard[T]) -> Unit

    start_auto_render starts an infinite loop of rendering.

    InMemoryBackend

    pub struct InMemoryBackend[T] {
    queue :
    Queue
    [Message[T]]
    dlq :
    Queue
    [Message[T]]
    in_flight :
    HashMap
    [String, Message[T]]
    policy : RetryPolicy
    next_id : Int
    count : Int
    dlq_count : Int
    }

    InMemoryBackend uses @aqueue.Queue from moonbitlang/async for local, non-blocking storage.

    InMemoryBackend::ack

    fn[T] InMemoryBackend::ack(self : InMemoryBackend[T], id : String) -> Unit

    ack confirms successful processing and removes from in-flight.

    InMemoryBackend::capabilities

    fn[T] InMemoryBackend::capabilities(_ : InMemoryBackend[T]) -> BackendCapabilities

    InMemoryBackend::dlq_size

    fn[T] InMemoryBackend::dlq_size(self : InMemoryBackend[T]) -> Int

    dlq_size returns the count of messages in the Dead Letter Queue.

    InMemoryBackend::health

    InMemoryBackend::nack

    async fn[T] InMemoryBackend::nack(self : InMemoryBackend[T], id : String) -> NackResult

    nack re-inserts the message into the queue or moves to DLQ if max attempts reached.

    InMemoryBackend::new

    fn[T] InMemoryBackend::new(capacity : Int, policy? : RetryPolicy) -> InMemoryBackend[T]

    new creates a new InMemoryBackend with a fixed capacity and optional policy.

    InMemoryBackend::pop

    async fn[T] InMemoryBackend::pop(self : InMemoryBackend[T]) -> Message[T]

    pop retrieves a message and marks it as in-flight.

    InMemoryBackend::push

    async fn[T] InMemoryBackend::push(self : InMemoryBackend[T], v : T) -> Unit

    push adds a message to the internal queue.

    InMemoryBackend::queue_metrics

    fn[T] InMemoryBackend::queue_metrics(self : InMemoryBackend[T]) -> QueueMetrics

    queue_metrics returns the current queue metrics.

    InMemoryBackend::size

    fn[T] InMemoryBackend::size(self : InMemoryBackend[T]) -> Int

    size returns the cached count of messages in the main queue.

    InMemoryBackend::to_relay_queue

    fn[T] InMemoryBackend::to_relay_queue(self : InMemoryBackend[T]) -> RelayQueue[T]

    to_relay_queue converts the backend into a generic RelayQueue interface.

    Incident

    pub enum Incident {
    BackendUnavailable
    WorkerFailures
    DeadLetterMessages
    PendingMessages
    } derive(Eq, ToJson,
    Debug
    )

    Incident represents a specific operational problem in Relay.

    Incident::severity

    fn Incident::severity(self : Incident) -> IncidentSeverity

    severity returns the operational severity of an incident.

    IncidentSeverity

    pub enum IncidentSeverity {
    Info
    Warning
    Critical
    } derive(Eq, ToJson,
    Debug
    )

    IncidentSeverity describes the operational severity of an incident.

    IncidentSeverity::to_string

    fn IncidentSeverity::to_string(self : IncidentSeverity) -> String

    Message

    pub struct Message[T] {
    id : String
    payload : T
    attempt_count : Int
    }

    Message[T] represents a wrapper for data sent through the queue.

    Message::new

    fn[T] Message::new(id : String, payload : T, attempt_count? : Int) -> Message[T]

    new creates a new message.

    NackResult

    pub enum NackResult {
    Requeued
    SentToDlq
    }

    Result of a negative acknowledgement.

    OtelAttribute

    pub struct OtelAttribute {
    key : String
    value : String
    }

    OtelAttribute represents a simple OpenTelemetry-compatible attribute.

    OtelRecord

    pub struct OtelRecord {
    name : String
    timestamp_ms : Int64
    attributes : Array[OtelAttribute]
    }

    OtelRecord represents a normalized OpenTelemetry-compatible event record.

    PrometheusMetric

    pub struct PrometheusMetric {
    name : String
    value : Float
    }

    PrometheusMetric represents a Prometheus-compatible metric sample.

    QueueInspection

    pub struct QueueInspection {
    status : SystemStatus
    queue_size : Int?
    dlq_size : Int?
    pending_count : Int64?
    backend_healthy : Bool
    }

    QueueInspection represents an operational view of a queue.

    QueueInspection::has_dlq

    fn QueueInspection::has_dlq(self : QueueInspection) -> Bool

    has_dlq returns true when DLQ messages are present.

    QueueInspection::has_pending

    fn QueueInspection::has_pending(self : QueueInspection) -> Bool

    has_pending returns true when pending messages are present.

    QueueInspection::is_empty

    fn QueueInspection::is_empty(self : QueueInspection) -> Bool

    is_empty returns true when the queue size is known and equal to zero.

    QueueInspection::summary

    fn QueueInspection::summary(self : QueueInspection) -> String

    summary returns a compact operational summary.

    QueueMetrics

    pub struct QueueMetrics {
    size : Int?
    dlq_size : Int?
    pending_count : Int64?
    }

    QueueMetrics is a backend-agnostic snapshot of queue state.

    RedisBackend

    pub struct RedisBackend[T] {
    client :
    Client

    key : String
    serialize : (T) -> String
    deserialize : (String) -> T
    next_id : Int
    }

    RedisBackend implements the storage interface for Relay using Redis/Valkey.

    RedisBackend::ack

    async fn[T] RedisBackend::ack(_self : RedisBackend[T], _id : String) -> Unit

    ack confirms message processing.

    Current Valkey backend pop semantics remove the message from the list when BLPOP returns, so ack is a no-op until visibility-timeout tracking is added.

    RedisBackend::capabilities

    fn[T] RedisBackend::capabilities(self : RedisBackend[T]) -> BackendCapabilities

    RedisBackend::health

    async fn[T] RedisBackend::health(self : RedisBackend[T]) -> BackendHealth

    RedisBackend::nack

    async fn[T] RedisBackend::nack(_self : RedisBackend[T], _id : String) -> NackResult

    nack is a no-op for the list-based Valkey backend.

    BLPOP removes the message immediately, so the backend cannot requeue by id.

    RedisBackend::new

    fn[T] RedisBackend::new(client :
    Client
    , key : String, serialize~ : (T) -> String, deserialize~ : (String) -> T) -> RedisBackend[T]

    new creates a RedisBackend instance with the provided client and serializers.

    RedisBackend::pop

    async fn[T] RedisBackend::pop(self : RedisBackend[T]) -> Message[T]

    pop extracts a message from the Redis queue in a blocking manner using BLPOP.

    RedisBackend::pop_nowait

    async fn[T] RedisBackend::pop_nowait(self : RedisBackend[T]) -> Message[T]?

    pop_nowait extracts a message without blocking, returning None when empty.

    RedisBackend::push

    async fn[T] RedisBackend::push(self : RedisBackend[T], v : T) -> Unit

    push sends a message to the Redis queue using RPUSH.

    RedisBackend::queue_metrics

    fn[T] RedisBackend::queue_metrics(_self : RedisBackend[T]) -> QueueMetrics

    queue_metrics returns the current queue metrics.

    RedisBackend::queue_metrics_async

    async fn[T] RedisBackend::queue_metrics_async(self : RedisBackend[T]) -> QueueMetrics

    RedisBackend::size

    async fn[T] RedisBackend::size(self : RedisBackend[T]) -> Int

    size returns the current number of queued messages.

    RedisBackend::to_relay_queue

    fn[T] RedisBackend::to_relay_queue(self : RedisBackend[T]) -> RelayQueue[T]

    to_relay_queue exports the backend as a generic RelayQueue.

    RedisStreamBackend

    pub struct RedisStreamBackend[T] {
    client :
    Client

    stream : String
    dlq_stream : String
    group : String
    consumer : String
    serialize : (T) -> String
    deserialize : (String) -> T
    }

    RedisStreamBackend::ack

    async fn[T] RedisStreamBackend::ack(self : RedisStreamBackend[T], id : String) -> Unit

    ack acknowledges a stream message by id.

    RedisStreamBackend::capabilities

    RedisStreamBackend::dead_letter

    async fn[T] RedisStreamBackend::dead_letter(self : RedisStreamBackend[T], value : T) -> Unit

    dead_letter writes a payload to the configured DLQ stream.

    RedisStreamBackend::health

    async fn[T] RedisStreamBackend::health(self : RedisStreamBackend[T]) -> BackendHealth

    RedisStreamBackend::init

    async fn[T] RedisStreamBackend::init(self : RedisStreamBackend[T]) -> Unit

    RedisStreamBackend::nack

    async fn[T] RedisStreamBackend::nack(_self : RedisStreamBackend[T], _id : String) -> NackResult

    nack leaves the stream message pending when only an id is available.

    Use nack_message when the payload is available and should be moved to DLQ.

    RedisStreamBackend::nack_message

    async fn[T] RedisStreamBackend::nack_message(self : RedisStreamBackend[T], msg : Message[T]) -> Unit

    nack_message moves the message payload to the DLQ and acknowledges the original stream entry.

    RedisStreamBackend::new

    fn[T] RedisStreamBackend::new(client :
    Client
    , stream : String, group : String, consumer : String, serialize~ : (T) -> String, deserialize~ : (String) -> T) -> RedisStreamBackend[T]

    RedisStreamBackend::new_with_dlq

    fn[T] RedisStreamBackend::new_with_dlq(client :
    Client
    , stream : String, dlq_stream : String, group : String, consumer : String, serialize~ : (T) -> String, deserialize~ : (String) -> T) -> RedisStreamBackend[T]

    RedisStreamBackend::pending_count

    async fn[T] RedisStreamBackend::pending_count(self : RedisStreamBackend[T]) -> Int64

    pending_count returns the number of unacknowledged messages.

    RedisStreamBackend::pop

    async fn[T] RedisStreamBackend::pop(self : RedisStreamBackend[T]) -> Message[T]

    pop reads one message from the stream consumer group.

    RedisStreamBackend::pop_block

    async fn[T] RedisStreamBackend::pop_block(self : RedisStreamBackend[T], block_ms : Int) -> Message[T]

    pop_block waits for a message for up to block_ms milliseconds.

    RedisStreamBackend::push

    async fn[T] RedisStreamBackend::push(self : RedisStreamBackend[T], value : T) -> Unit

    RedisStreamBackend::queue_metrics

    fn[T] RedisStreamBackend::queue_metrics(self : RedisStreamBackend[T]) -> QueueMetrics

    RedisStreamBackend::queue_metrics_async

    async fn[T] RedisStreamBackend::queue_metrics_async(self : RedisStreamBackend[T]) -> QueueMetrics

    RedisStreamBackend::recover_or_pop

    async fn[T] RedisStreamBackend::recover_or_pop(self : RedisStreamBackend[T], min_idle_ms : Int, block_ms : Int) -> Message[T]

    recover_or_pop first tries to recover a pending message, then falls back to blocking reads for new stream entries.

    RedisStreamBackend::recover_pending

    async fn[T] RedisStreamBackend::recover_pending(self : RedisStreamBackend[T], min_idle_ms : Int) -> Message[T]?

    recover_pending claims one pending message idle for at least min_idle_ms.

    RedisStreamBackend::to_relay_queue

    fn[T] RedisStreamBackend::to_relay_queue(self : RedisStreamBackend[T]) -> RelayQueue[T]

    to_relay_queue exports the stream backend as a generic RelayQueue.

    RedisStreamBackend::to_relay_queue_with_recovery

    fn[T] RedisStreamBackend::to_relay_queue_with_recovery(self : RedisStreamBackend[T], min_idle_ms : Int, block_ms : Int) -> RelayQueue[T]

    to_relay_queue_with_recovery exports the stream backend as a RelayQueue whose pop path first recovers pending entries before blocking for new ones.

    RelayMetrics

    pub struct RelayMetrics {
    worker : WorkerMetrics?
    queue : QueueMetrics?
    health : BackendHealth?
    }

    RelayMetrics combines queue and worker telemetry.

    RelayQueue

    pub struct RelayQueue[T] {
    push_fn : async (T) -> Unit
    pop_fn : async () -> Message[T]
    ack_fn : async (String) -> Unit
    nack_fn : async (String) -> NackResult
    size_fn : () -> Int
    }

    RelayQueue is the main entry point for interacting with the message queue. It uses a closure-based backend abstraction to support multiple storage engines (Memory, Redis, etc.).

    RelayQueue::ack

    async fn[T] RelayQueue::ack(self : RelayQueue[T], id : String) -> Unit

    ack confirms that a message has been processed successfully. The backend will permanently remove the message from its tracking system.

    RelayQueue::nack

    async fn[T] RelayQueue::nack(self : RelayQueue[T], id : String) -> NackResult

    nack (negative acknowledgement) informs the queue that processing failed. The backend will typically re-queue the message for another attempt, unless it exceeds the RetryPolicy.

    RelayQueue::new

    fn[T] RelayQueue::new(push~ : async (T) -> Unit, pop~ : async () -> Message[T], ack~ : async (String) -> Unit, nack~ : async (String) -> NackResult, size~ : () -> Int) -> RelayQueue[T]

    new creates a new RelayQueue with the provided backend functions.

    RelayQueue::pop

    async fn[T] RelayQueue::pop(self : RelayQueue[T]) -> Message[T]

    pop removes and returns a value from the queue. Suspends if the queue is empty. In V3, a popped message is considered "In Flight" until acknowledged.

    RelayQueue::push

    async fn[T] RelayQueue::push(self : RelayQueue[T], value : T) -> Unit

    push adds a value to the queue. Asynchronous and thread-safe via the underlying backend.

    RelayQueue::size

    fn[T] RelayQueue::size(self : RelayQueue[T]) -> Int

    size returns the current number of items in the queue.

    RelaySnapshot

    pub struct RelaySnapshot {
    collected_at_ms : Int64
    metrics : RelayMetrics
    }

    RelaySnapshot represents a metrics snapshot collected at a specific time.

    RelaySnapshot::dlq_size

    fn RelaySnapshot::dlq_size(self : RelaySnapshot) -> Int?

    dlq_size returns the known DLQ size, if available.

    RelaySnapshot::has_failures

    fn RelaySnapshot::has_failures(self : RelaySnapshot) -> Bool

    has_failures returns true when worker failures or ack/nack failures are present.

    RelaySnapshot::is_healthy

    fn RelaySnapshot::is_healthy(self : RelaySnapshot) -> Bool

    is_healthy returns true when health is present and healthy.

    RelaySnapshot::new

    new creates a timestamped RelaySnapshot.

    RelaySnapshot::pending_count

    fn RelaySnapshot::pending_count(self : RelaySnapshot) -> Int64?

    pending_count returns the known pending message count, if available.

    RelaySnapshot::queue_size

    fn RelaySnapshot::queue_size(self : RelaySnapshot) -> Int?

    queue_size returns the known queue size, if available.

    RelaySnapshot::requires_attention

    fn RelaySnapshot::requires_attention(self : RelaySnapshot) -> Bool

    requires_attention returns true when the snapshot is degraded or unhealthy.

    RelaySnapshot::status

    status returns a high-level health status for the snapshot.

    RelaySnapshot::status_message

    fn RelaySnapshot::status_message(self : RelaySnapshot) -> String

    status_message returns a short human-readable status summary.

    RetryPolicy

    pub struct RetryPolicy {
    max_attempts : Int
    }

    RetryPolicy defines how the queue handles failed message processing.

    RetryPolicy::default

    fn RetryPolicy::default() -> RetryPolicy

    default_policy provides a standard policy with 3 max attempts.

    RetryPolicy::new

    fn RetryPolicy::new(max_attempts : Int) -> RetryPolicy

    new_policy creates a custom retry policy.

    SystemStatus

    pub enum SystemStatus {
    Healthy
    Degraded
    Unhealthy
    } derive(Eq, ToJson,
    Debug
    )

    SystemStatus summarizes the current observable state of Relay.

    SystemStatus::to_string

    fn SystemStatus::to_string(self : SystemStatus) -> String

    TelemetryEvent

    pub struct TelemetryEvent {
    timestamp_ms : Int64
    status : SystemStatus
    severity : IncidentSeverity?
    incident_count : Int
    summary : String
    }

    TelemetryEvent is a normalized event that can later be exported to OpenTelemetry, Prometheus, JSON, logs, or other observability sinks.

    TelemetryEvent::to_otel_record

    fn TelemetryEvent::to_otel_record(self : TelemetryEvent) -> OtelRecord

    to_otel_record converts a Relay telemetry event into an OpenTelemetry-compatible record.

    TelemetryEvent::to_prometheus_metrics

    fn TelemetryEvent::to_prometheus_metrics(self : TelemetryEvent) -> Array[PrometheusMetric]

    to_prometheus_metrics converts a telemetry event into Prometheus-compatible metrics.

    WorkerMetrics

    pub struct WorkerMetrics {
    processed : Int
    succeeded : Int
    failed : Int
    retries : Int
    dlq_routed : Int
    ack_failed : Int
    nack_failed : Int
    uptime_ms : Int64
    last_success_at_ms : Int64?
    last_failure_at_ms : Int64?
    }

    WorkerMetrics is a backend-agnostic snapshot of worker activity.

    WorkerPool

    pub struct WorkerPool[T] {
    queue : RelayQueue[T]
    concurrency : Int
    stats : WorkerStats
    }

    WorkerPool manages a group of concurrent workers that process messages from the queue.

    WorkerPool::metrics

    fn[T] WorkerPool::metrics(self : WorkerPool[T]) -> WorkerMetrics

    metrics returns the current worker processing counters.

    WorkerPool::new

    fn[T] WorkerPool::new(queue : RelayQueue[T], concurrency~ : Int) -> WorkerPool[T]

    new creates a new worker pool with the specified concurrency.

    WorkerPool::run

    async fn[T] WorkerPool::run(self : WorkerPool[T], handler : async (T) -> Unit) -> Unit

    run starts the pool. Each worker is launched as a background task within a TaskGroup.

    WorkerPool::stats

    fn[T] WorkerPool::stats(self : WorkerPool[T]) -> WorkerStats

    stats returns the current worker processing counters.

    WorkerStats

    pub struct WorkerStats {
    processed : Int
    succeeded : Int
    failed : Int
    retries : Int
    dlq_routed : Int
    ack_failed : Int
    nack_failed : Int
    started_at_ms : Int64
    last_success_at_ms : Int64?
    last_failure_at_ms : Int64?
    }

    WorkerStats tracks basic worker processing counters.

    WorkerStats::has_failures

    fn WorkerStats::has_failures(self : WorkerStats) -> Bool

    WorkerStats::new

    new creates empty worker stats.

    WorkerStats::uptime_ms

    fn WorkerStats::uptime_ms(self : WorkerStats) -> Int64

    collect

    fn collect(worker : WorkerMetrics?, queue : QueueMetrics?, health : BackendHealth?) -> RelayMetrics

    collect combines worker, queue, and backend health telemetry into a single snapshot.

    collect_queue

    fn collect_queue(queue : QueueMetrics, health : BackendHealth) -> RelayMetrics

    collect_queue creates a telemetry snapshot containing only queue metrics.

    collect_snapshot

    fn collect_snapshot(worker : WorkerMetrics?, queue : QueueMetrics?, health : BackendHealth?) -> RelaySnapshot

    collect_snapshot combines telemetry and wraps it in a timestamped snapshot.

    collect_worker

    fn collect_worker(worker : WorkerMetrics, health : BackendHealth) -> RelayMetrics

    collect_worker creates a telemetry snapshot containing only worker metrics.

    detect_incidents

    fn detect_incidents(report : AdminReport) -> Array[Incident]

    detect_incidents analyzes an administrative report.

    detect_incidents_with_capabilities

    fn detect_incidents_with_capabilities(report : AdminReport, capabilities : BackendCapabilities) -> Array[Incident]

    from_report

    fn from_report(report : AdminReport, incidents : Array[Incident]) -> TelemetryEvent

    from_report converts an administrative report and detected incidents into a normalized telemetry event.

    has_incidents

    fn has_incidents(report : AdminReport) -> Bool

    has_incidents returns true when incidents are detected.

    highest_severity

    fn highest_severity(incidents : Array[Incident]) -> IncidentSeverity?

    highest_severity returns the highest severity among incidents.

    incident_count

    fn incident_count(report : AdminReport) -> Int

    incident_count returns the number of detected incidents.

    inspect

    fn inspect(snapshot : RelaySnapshot) -> QueueInspection

    inspect builds an operational queue inspection from a telemetry snapshot.

    report

    fn report(inspection : QueueInspection) -> AdminReport

    report builds an administrative report from a queue inspection.

    start_worker

    async fn[T] start_worker(queue : RelayQueue[T], handler : (Message[T]) -> Unit) -> Unit

    start_worker starts an infinite loop that pops messages from the queue and passes them to a handler.

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io