Documentation
¶
Overview ¶
Package mqlite is the native Go SDK for mqlite (design §17.1). The same method set drives two modes:
Open — a remote client talking to an mqlite broker over HTTP.
OpenEmbedded — the queue engine in-process (like goqite), with same-DB
transactional enqueue and a one-line upgrade to a broker.
Settlement methods hang off *Message so the lock token never leaks into user code, and receive comes in two tiers: low-level Receive (you settle) and high-level Receiver.Run (handler returns nil -> Complete, error -> Abandon).
Example (Embedded) ¶
Example_embedded runs the whole queue in-process — no broker, no HTTP — against a local SQLite file, and shows the single-process / single-writer guarantee: a second opener of the same DB is rejected with ErrDBLocked (MQLITE-6 / MQLITE-15).
package main
import (
"context"
"errors"
"fmt"
"log"
"os"
"path/filepath"
"github.com/mqlitehq/mqlite"
)
func main() {
ctx := context.Background()
dir, err := os.MkdirTemp("", "mqlite-example-*")
if err != nil {
log.Fatal(err)
}
defer func() { _ = os.RemoveAll(dir) }()
dsn := "file:" + filepath.Join(dir, "mq.db")
eng, err := mqlite.OpenEmbedded(ctx, dsn)
if err != nil {
log.Fatal(err)
}
defer func() { _ = eng.Close() }()
if err := eng.CreateQueue(ctx, "orders", mqlite.QueueConfig{}); err != nil {
log.Fatal(err)
}
if _, err := eng.SendOne(ctx, "orders", mqlite.OutMessage{Body: []byte("order-42")}); err != nil {
log.Fatal(err)
}
msgs, err := eng.Receive(ctx, "orders", mqlite.RecvOpts{})
if err != nil {
log.Fatal(err)
}
for _, m := range msgs {
fmt.Printf("received: %s\n", m.Body)
_ = m.Complete(ctx) // at-least-once; the handler must be idempotent
}
// Embedded mode is single-writer: a second process — or a second OpenEmbedded on
// the same file — is rejected rather than racing the first.
if _, err := mqlite.OpenEmbedded(ctx, dsn); errors.Is(err, mqlite.ErrDBLocked) {
fmt.Println("second open rejected: single writer")
}
}
Output: received: order-42 second open rejected: single writer
Index ¶
- Constants
- Variables
- func GenerateToken() string
- type AbandonOpts
- type Client
- func (c *Client) Cancel(ctx context.Context, queue string, seq int64) error
- func (c *Client) Close() error
- func (c *Client) CompleteBatch(ctx context.Context, queue string, msgs ...*Message) ([]SettleResult, error)
- func (c *Client) CreateQueue(ctx context.Context, name string, cfg QueueConfig) error
- func (c *Client) ListQueues(ctx context.Context) ([]QueueInfo, error)
- func (c *Client) Peek(ctx context.Context, queue string, opts ...PeekOpts) ([]*PeekedMessage, error)
- func (c *Client) Purge(ctx context.Context, queue string, opts ...PurgeOpts) (int, error)
- func (c *Client) Receive(ctx context.Context, queue string, opts ...RecvOpts) ([]*Message, error)
- func (c *Client) Receiver(queue string, opts ...ReceiverOption) *Receiver
- func (c *Client) Redrive(ctx context.Context, dlqQueue string, opts ...RedriveOpts) (int, error)
- func (c *Client) Send(ctx context.Context, queue string, msgs ...OutMessage) ([]int64, error)
- func (c *Client) SendOne(ctx context.Context, queue string, m OutMessage, opts ...SendOpts) (int64, error)
- func (c *Client) Stats(ctx context.Context, queue string) (Metrics, error)
- func (c *Client) Subscribe(ctx context.Context, topic, name string, f *Filter) error
- type Embedded
- func (e *Embedded) Cancel(ctx context.Context, queue string, seq int64) error
- func (e *Embedded) Close() error
- func (e *Embedded) Compact(ctx context.Context, full bool) error
- func (e *Embedded) CompleteBatch(ctx context.Context, queue string, msgs ...*Message) ([]SettleResult, error)
- func (e *Embedded) CreateQueue(ctx context.Context, name string, cfg QueueConfig) error
- func (e *Embedded) Engine() *engine.Engine
- func (e *Embedded) ListQueues(ctx context.Context) ([]QueueInfo, error)
- func (e *Embedded) Peek(ctx context.Context, queue string, opts ...PeekOpts) ([]*PeekedMessage, error)
- func (e *Embedded) Purge(ctx context.Context, queue string, opts ...PurgeOpts) (int, error)
- func (e *Embedded) Receive(ctx context.Context, queue string, opts ...RecvOpts) ([]*Message, error)
- func (e *Embedded) Receiver(queue string, opts ...ReceiverOption) *Receiver
- func (e *Embedded) Redrive(ctx context.Context, dlqQueue string, opts ...RedriveOpts) (int, error)
- func (e *Embedded) Send(ctx context.Context, queue string, msgs ...OutMessage) ([]int64, error)
- func (e *Embedded) SendOne(ctx context.Context, queue string, m OutMessage, opts ...SendOpts) (int64, error)
- func (e *Embedded) Serve(ctx context.Context, addr string, opts ...ServeOption) error
- func (e *Embedded) Stats(ctx context.Context, queue string) (Metrics, error)
- func (e *Embedded) Subscribe(ctx context.Context, topic, name string, f *Filter) error
- func (e *Embedded) Tx(ctx context.Context, fn func(*engine.EngineTx) error) error
- type EmbeddedOption
- func WithClock(now func() int64) EmbeddedOption
- func WithDBAuthToken(tok string) EmbeddedOption
- func WithDLQRetention(maxAge time.Duration, maxCount int, maxBytes int64) EmbeddedOption
- func WithLogger(lg *slog.Logger) EmbeddedOption
- func WithMaxMessageBytes(n int64) EmbeddedOption
- func WithSynchronous(mode string) EmbeddedOption
- func WithoutBackground() EmbeddedOption
- type Filter
- type Message
- func (m *Message) Abandon(ctx context.Context, opts ...AbandonOpts) error
- func (m *Message) Complete(ctx context.Context) error
- func (m *Message) Defer(ctx context.Context) error
- func (m *Message) Reject(ctx context.Context, opts ...RejectOpts) error
- func (m *Message) Renew(ctx context.Context) error
- type Metrics
- type Option
- type OrderingMode
- type OutMessage
- type PeekOpts
- type PeekedMessage
- type PurgeOpts
- type QueueConfig
- type QueueInfo
- type Receiver
- type ReceiverOption
- type RecvOpts
- type RedriveOpts
- type RejectOpts
- type SendOpts
- type ServeOption
- type SettleResult
- type State
Examples ¶
Constants ¶
const ( OrderStandard = engine.OrderStandard OrderGroupFIFO = engine.OrderGroupFIFO OrderStrictFIFO = engine.OrderStrictFIFO )
const ( Active = engine.StateActive Locked = engine.StateLocked Deferred = engine.StateDeferred Scheduled = engine.StateScheduled DeadLettered = engine.StateDeadLettered )
const TokenPrefix = "mqk_"
TokenPrefix is the conventional prefix for a broker auth token, so a token is recognizable at a glance (and greppable in logs/config). It is a convention, not a requirement — any non-empty string in MQLITE_TOKENS is accepted as a token.
Variables ¶
var ( ErrLockLost = engine.ErrLockLost ErrNotFound = engine.ErrNotFound ErrQueueNotFound = engine.ErrQueueNotFound ErrDedupConflict = engine.ErrDedupConflict ErrMessageTooLarge = engine.ErrMessageTooLarge ErrNameConflict = engine.ErrNameConflict ErrGroupRequired = engine.ErrGroupRequired // ErrDBLocked is returned by OpenEmbedded when the local file DB is already open // in another process: embedded mode is single-process, single-writer (MQLITE-6). ErrDBLocked = engine.ErrDBLocked )
Re-exported sentinel errors so callers can use errors.Is on either mode.
Functions ¶
func GenerateToken ¶ added in v0.1.1
func GenerateToken() string
GenerateToken mints a fresh broker auth token: the "mqk_" prefix plus 128 bits of crypto/rand, hex-encoded (e.g. "mqk_" + 32 hex chars). Use it to seed MQLITE_TOKENS / WithTokens, or let `mqlite serve` call it automatically when no token is configured (secure by default). 128 bits is unguessable; bump the byte count here if a longer secret is ever wanted.
Types ¶
type AbandonOpts ¶
type AbandonOpts struct {
Delay time.Duration // re-hide for this long before redelivery (backoff)
}
AbandonOpts configures a Message.Abandon call.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a remote mqlite client (Connect-style JSON over HTTP).
func (*Client) CompleteBatch ¶ added in v0.1.1
func (c *Client) CompleteBatch(ctx context.Context, queue string, msgs ...*Message) ([]SettleResult, error)
CompleteBatch completes many received messages in one round-trip — the fix for the drain N+1 (settling a received batch one HTTP call at a time). Messages should share one queue; a stale lock comes back as Ok=false rather than failing the batch.
func (*Client) CreateQueue ¶
CreateQueue creates or updates a queue.
func (*Client) ListQueues ¶
ListQueues lists queues/subscriptions.
func (*Client) Peek ¶
func (c *Client) Peek(ctx context.Context, queue string, opts ...PeekOpts) ([]*PeekedMessage, error)
Peek browses without locking.
func (*Client) Purge ¶
Purge permanently deletes dead-lettered messages (PurgeOpts scopes it; no opts purges the whole DLQ). Returns count deleted.
func (*Client) Receive ¶
Receive claims up to N messages (Peek-Lock by default), with optional long-poll. RecvOpts.Pick fetches previously-deferred messages by seq instead of claiming.
func (*Client) Receiver ¶
func (c *Client) Receiver(queue string, opts ...ReceiverOption) *Receiver
Receiver returns a stateful receive loop bound to this client.
func (*Client) Send ¶
Send enqueues one or many messages in one request/transaction (use SendOne for a single seq return or At() scheduling).
func (*Client) SendOne ¶
func (c *Client) SendOne(ctx context.Context, queue string, m OutMessage, opts ...SendOpts) (int64, error)
SendOne enqueues one message and returns its seq. A dedup conflict (same id, different body) surfaces as ErrDedupConflict. SendOpts.At schedules delayed delivery.
type Embedded ¶
type Embedded struct {
// contains filtered or unexported fields
}
Embedded runs the queue engine in-process (like goqite), exposing the same method set as the remote Client plus same-DB transactional enqueue (Tx) and a one-line upgrade to a network broker (Serve). See design §4.5.
func OpenEmbedded ¶
OpenEmbedded opens the engine on a DB DSN: file:./mq.db | :memory: | libsql://host
func (*Embedded) Compact ¶ added in v0.1.1
Compact reclaims free DB pages to the OS: `PRAGMA incremental_vacuum` (no global lock; new local DBs default to auto_vacuum=INCREMENTAL), or a full `VACUUM` when full=true (rewrites the file, global lock — maintenance only). Local-only.
func (*Embedded) CompleteBatch ¶ added in v0.1.1
func (e *Embedded) CompleteBatch(ctx context.Context, queue string, msgs ...*Message) ([]SettleResult, error)
CompleteBatch completes many received messages in one transaction (mirrors the remote Client method; for the in-process engine there is no round-trip to save, but it keeps the API symmetric and settles atomically).
func (*Embedded) CreateQueue ¶
func (*Embedded) ListQueues ¶
func (*Embedded) Purge ¶
Purge permanently deletes dead-lettered messages (PurgeOpts scopes it; no opts purges the whole DLQ). Returns count deleted.
func (*Embedded) Receiver ¶
func (e *Embedded) Receiver(queue string, opts ...ReceiverOption) *Receiver
Receiver returns a stateful receive loop bound to the embedded engine.
func (*Embedded) SendOne ¶
func (e *Embedded) SendOne(ctx context.Context, queue string, m OutMessage, opts ...SendOpts) (int64, error)
SendOne enqueues one message. A dedup conflict surfaces as ErrDedupConflict. SendOpts.At schedules delayed delivery.
type EmbeddedOption ¶
type EmbeddedOption func(*embeddedConfig)
EmbeddedOption configures OpenEmbedded.
func WithClock ¶
func WithClock(now func() int64) EmbeddedOption
WithClock injects a test clock returning epoch ms.
func WithDBAuthToken ¶
func WithDBAuthToken(tok string) EmbeddedOption
WithDBAuthToken supplies the auth token for a remote libSQL/Turso DSN. The token is passed in by the caller (typically from an env var) — never compiled in.
func WithDLQRetention ¶ added in v0.1.1
func WithDLQRetention(maxAge time.Duration, maxCount int, maxBytes int64) EmbeddedOption
WithDLQRetention bounds the dead-letter queue so a long-running broker can't grow without limit (MQLITE-21). A background pass drops dead letters oldest-first when they are older than maxAge, beyond maxCount per queue, or over maxBytes of body per queue; pass 0 to leave a dimension unbounded. ONLY the DLQ is affected — undelivered and in-flight messages are never deleted. Off by default for the embedded library; the `mqlite serve` broker enables a sane default (see cmd/mqlite).
func WithLogger ¶
func WithLogger(lg *slog.Logger) EmbeddedOption
WithLogger routes background-loop failures to lg (nil -> slog.Default()).
func WithMaxMessageBytes ¶
func WithMaxMessageBytes(n int64) EmbeddedOption
WithMaxMessageBytes caps message body size (0 -> 1 MiB default).
func WithSynchronous ¶
func WithSynchronous(mode string) EmbeddedOption
WithSynchronous sets the local SQLite PRAGMA synchronous level — the durability vs throughput knob (MQLITE-7). "NORMAL" (default) is fast and durable across a process crash, but a sudden OS/power loss can drop the last few not-yet- checkpointed commits; "FULL" fsyncs every commit (safer, slower). Database-wide (SQLite has no per-queue sync); ignored for remote Turso DSNs.
func WithoutBackground ¶
func WithoutBackground() EmbeddedOption
WithoutBackground disables the maintenance loops (tests drive them manually).
type Message ¶
type Message struct {
SequenceNumber int64
Body []byte
MessageID string
GroupID string
CorrelationID string
ReplyTo string
Subject string
ContentType string
Properties map[string]string
DeliveryCount int
EnqueuedAt time.Time
LockedUntil time.Time
// contains filtered or unexported fields
}
Message is a delivered message handle. The lock token is held internally and never exposed, so settlement can't be misrouted (§17.1).
func (*Message) Abandon ¶
func (m *Message) Abandon(ctx context.Context, opts ...AbandonOpts) error
Abandon releases the lock for immediate redelivery (optionally after a delay).
type Option ¶
type Option func(*config)
Option configures Open.
func WithHTTPClient ¶
WithHTTPClient supplies a custom *http.Client (e.g. for TLS config).
type OrderingMode ¶
type OrderingMode = engine.OrderingMode
OrderingMode mirrors engine.OrderingMode for queue-level delivery ordering.
type OutMessage ¶
type OutMessage struct {
Body []byte
MessageID string // dedup/idempotency key; empty -> body SHA-256 when dedup on
// GroupID is an ordering/partition key (= SQS MessageGroupId, ASB SessionId):
// same GroupID = strict in-order (FIFO per group); empty = own group (max
// parallelism). NOT a consumer group — competing consumers just Receive the
// same queue; peek-lock gives each message to exactly one.
GroupID string
CorrelationID string
ReplyTo string // = ASB ReplyTo; opaque address the consumer should reply to
Subject string // = ASB Label
ContentType string
Properties map[string]string // custom KV (headers)
TTL time.Duration // 0 -> queue default
}
OutMessage is a message to send. Body is opaque; broker never parses it.
type PeekOpts ¶
type PeekOpts struct {
From int64 // start browsing at this seq
State State // filter by state
Max int // cap results
}
PeekOpts configures a Peek call.
type PeekedMessage ¶
type PeekedMessage struct {
SequenceNumber int64
State State
Body []byte
MessageID string
GroupID string
CorrelationID string
ReplyTo string
Subject string
ContentType string
Properties map[string]string
DeliveryCount int
EnqueuedAt time.Time
VisibleAt time.Time
LockedUntil time.Time
}
PeekedMessage is a read-only browse result.
type PurgeOpts ¶
type PurgeOpts struct {
Max int // cap how many messages are deleted
OlderThan time.Duration // only delete messages older than this
}
PurgeOpts configures a Purge call.
type QueueConfig ¶
type QueueConfig struct {
LockDuration time.Duration
MaxDeliveryCount int
DefaultTTL time.Duration
DeadLetterOnExpire *bool
DedupWindow time.Duration
Ordering OrderingMode // "" -> standard
// Per-queue DLQ retention overrides (MQLITE-29). For each: 0 -> inherit the
// broker default; >0 -> this queue's drop-oldest bound; a negative value ->
// explicitly unbounded (opt out of the default).
DLQMaxAge time.Duration
DLQMaxCount int
DLQMaxBytes int64
}
QueueConfig configures a queue (durations as time.Duration).
type Receiver ¶
type Receiver struct {
// contains filtered or unexported fields
}
Receiver is a stateful receive loop. handler returning nil auto-Completes; returning error auto-Abandons (§17.1).
type ReceiverOption ¶
type ReceiverOption func(*receiverConfig)
ReceiverOption configures a Receiver.
func WithAutoRenew ¶
func WithAutoRenew() ReceiverOption
WithAutoRenew keeps locks alive with a background heartbeat for long handlers.
func WithConcurrency ¶
func WithConcurrency(n int) ReceiverOption
WithConcurrency sets how many messages are processed in parallel.
func WithPrefetch ¶
func WithPrefetch(n int) ReceiverOption
WithPrefetch sets how many messages to claim per receive (defaults to concurrency).
type RecvOpts ¶
type RecvOpts struct {
Max int // most messages to claim (0 -> 1)
Wait time.Duration // long-poll wait (0 -> don't wait); capped at 20s
AtMostOnce bool // receive-and-delete (no lock, no settle)
Attempt string // idempotent-receive key; a retry replays the same batch
Pick []int64 // fetch these deferred seqs by seq instead of claiming
}
RecvOpts configures a Receive call.
type RedriveOpts ¶
type RedriveOpts struct {
To string // target queue (empty -> back to source)
Max int // cap how many messages move
OlderThan time.Duration // only move messages older than this
Rate int // throughput limit per second
}
RedriveOpts configures a Redrive call.
type RejectOpts ¶
type RejectOpts struct {
Reason string // dead-letter reason
Detail string // dead-letter description
}
RejectOpts configures a Message.Reject call.
type ServeOption ¶
type ServeOption func(*serveConfig)
ServeOption configures Serve.
func WithTokenCSV ¶
func WithTokenCSV(csv string) ServeOption
WithTokenCSV sets accepted Bearer tokens from a comma-separated string (env-friendly).
func WithTokens ¶
func WithTokens(tokens ...string) ServeOption
WithTokens sets the accepted Bearer tokens for the broker.
func WithVersion ¶ added in v0.1.1
func WithVersion(v string) ServeOption
WithVersion sets the version string the broker reports on its open "/" discovery endpoint (typically the CLI/build version).
type SettleResult ¶ added in v0.1.1
SettleResult is the per-message outcome of CompleteBatch (Ok=false = the lock was lost/expired for that message — not a fatal error for the batch).
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
mqlite
command
Command mqlite is the single-binary CLI: run a broker, or produce/consume/ administer queues against a local DB (embedded) or a remote broker (client).
|
Command mqlite is the single-binary CLI: run a broker, or produce/consume/ administer queues against a local DB (embedded) or a remote broker (client). |
|
mqlite-mcp
command
Command mqlite-mcp is a Model Context Protocol (MCP) server that exposes the mqlite broker as agent tools.
|
Command mqlite-mcp is a Model Context Protocol (MCP) server that exposes the mqlite broker as agent tools. |
|
Package server exposes an mqlite Engine as a Connect-style JSON-over-HTTP broker (design §7).
|
Package server exposes an mqlite Engine as a Connect-style JSON-over-HTTP broker (design §7). |
|
test
|
|
|
bench
command
Command mqlite-bench stress-tests the local SQLite engine (embedded, no HTTP) across several high-frequency request patterns, and attributes per-scenario CPU and disk I/O via /proc/self (Linux/Docker).
|
Command mqlite-bench stress-tests the local SQLite engine (embedded, no HTTP) across several high-frequency request patterns, and attributes per-scenario CPU and disk I/O via /proc/self (Linux/Docker). |
|
sdkcheck
command
Command sdkcheck is the SDK end-to-end suite (the "用 SDK" path).
|
Command sdkcheck is the SDK end-to-end suite (the "用 SDK" path). |
|
Package wire defines the JSON-over-HTTP contract shared by the mqlite broker (server) and the Go SDK client.
|
Package wire defines the JSON-over-HTTP contract shared by the mqlite broker (server) and the Go SDK client. |