Rate-Limited Message Manager (Nim)

Rate limiter for sending messages to a provided delivery service. Implements a token-bucket per epoch, queues by priority, and persists queue and quota across restarts. Intended to provide a good UX for sending messages in an RLN-protected network, so that developers can queue, prioritize and inform end users when quotas might be close to being consumed.

Features

  • Rate limit per epoch: Fixed-capacity token bucket (messages per epoch, RLN-style window).
  • Priorities: Critical, Normal, Optional.
  • Low/empty quota behavior:
    • Low quota: Critical sent, Normal queued, Optional dropped.
    • Exhausted: Critical queued, Normal queued, Optional dropped.
  • Batch all-or-none: Pass messages as a batch; either the whole batch is sent, queued, or dropped.
  • Status tracking: PassedToSender, Enqueued, Dropped, DroppedBatchTooLarge, DroppedFailedToEnqueue.
  • Persistence: Queues and quota state survive restarts (SQLite).

Install

  • Built as part of this Nimble project. Add this repo as a dependency or develop locally, then import ratelimit/ratelimit_manager and ratelimit/store.

API (essentials)

  • Create: await RateLimitStore[T].new(db); await RateLimitManager[T].new(store, sender, capacity, duration, sleepDuration)
  • Run: await manager.start() / await manager.stop()
  • Send: await manager.sendOrEnqueue(@[(msgId, msg), ...], Priority)
  • Quota: manager.getQuota()(remaining, total)
  • Message Status: await manager.getMessageStatus(msgId)

Notes:

  • Batches larger than 30% of total capacity are dropped to prevent starvation (DroppedBatchTooLarge).
  • Sender is user-provided. Message outcome is recorded via MessageStatus.

Persistence

Backed by SQLite. Migrations create the following tables:

  • kv_store (stores bucket state)
  • ratelimit_queues (persisted batches per priority)
  • ratelimit_message_status (latest status per msg_id)

Apply migrations via chat_sdk/migration.runMigrations(db).

Tests

See tests/test_ratelimit_manager.nim for usage and expected behaviors.