mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-07-23 00:30:18 +00:00
* chore: drop rate-limit stage from reliable channel send pipeline Collapses the outgoing pipeline to `segmentation -> sds -> encryption -> dispatch` by folding the encrypt-and-dispatch tail of `onReadyToSend` directly into `send()`. Removes the `RateLimitManager` field, its constructor param, the `ReadyToSendEvent` listener, and the `awaitingDispatch` accounting that only existed to bridge the event-bus hop between `send()` and `onReadyToSend`. The `rate_limit_manager.nim` module itself is untouched — it will be relocated to the messaging layer (co-located with RLN) in a follow-up commit, where per-epoch admission actually belongs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: relocate RateLimitManager to messaging layer Moves rate_limit_manager.nim from `logos_delivery/channels/` to `logos_delivery/messaging/rate_limit_manager/` — the correct owner now that admission sits alongside RLN in the messaging layer instead of being fanned out to per-channel event listeners. The API surface changes: - `enqueueToSend` + `ReadyToSendEvent` (broker-based fan-out to a ReliableChannel listener) is replaced by `admit(msg): Future[Result[ void, RateLimitError]]`. Callers now branch directly on the result instead of subscribing to an event. - `channelId`, `SdsChannelID` and the SDS import are dropped — the messaging layer has no notion of channels; SDS was a channels-layer concern that only survived on this type because of the old broker fan-out. - `brokerCtx` is dropped for the same reason. Epoch config (`epochPeriodSec`), the wall-clock `currentEpochStart`, `queue`, `dequeueReady`, and `resetEpoch` are preserved exactly as the original owner designed them — this refactor is intentionally scoped to the API surface, not the epoch mechanism. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: meter SendService transmissions through RateLimitManager Wires the relocated RateLimitManager into the messaging layer at the transmission stage rather than the API entry point: - MessagingClientConf gains a rateLimit: RateLimitConfig field (defaulting to DefaultEpochPeriodSec / DefaultMessagesPerEpoch), and MessagingClient.new hands the constructed manager to SendService. - SendService consults admit() before the first transmission of a task, both in send() and in the retry loop. Re-publishes of an already-propagated message (firstPropagatedTime set) skip admission: they resend the same bytes, which reuse the same RLN proof/nullifier and consume no fresh epoch slot. - An over-budget task parks in the task cache as NextRoundRetry; the service loop re-admits it as the epoch budget frees up. The skeleton admit() is a pass-through, so behaviour is unchanged today. Gating transmissions instead of MessagingClient.send keeps SDS repair rebroadcasts free of API-entry rejection (SDS decides that a repair is needed; the transmission scheduler decides when it fits the budget) while every wire transmission still draws from one node-wide budget -- which network-side RLN enforcement applies to repairs regardless of any local bypass. It is also where RLN proof attachment must happen, since proofs bind to the epoch current at transmission time. Adds tests/messaging/test_rate_limit_manager.nim covering the current disabled + enabled pass-through behaviour, wired into all_tests_waku.nim. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: make MessagingClientConf.rateLimit reachable, warn on dead channel knobs Addresses two review findings on the move PR: - `rateLimit` was a plain `RateLimitConfig`, but `merge` only copies `Opt` fields (`when oField is Opt`), so every override path (`LogosDeliveryConf.init`, JSON `messagingOverrides`) silently dropped it and the field was always taken from `base` — unsettable by any caller. Make it `Opt[RateLimitConfig]` like every other field; `MessagingClient.new` falls back to `DefaultRateLimitConfig` (new const, rate limiting disabled) when unset. Adds a merge test. - The channel-level knobs (`rateLimitEnabled` / `rateLimitEpochPeriodSec` / `rateLimitMessagesPerEpoch`) are still parsed but unread since rate limiting moved to the messaging client, so setting them was silently ignored. `ReliableChannelManager.new` now logs a deprecation warning when any is set. Full removal remains a follow-up API decision. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
22 lines
781 B
Nim
22 lines
781 B
Nim
## Reliable Channel layer API — channel send operation.
|
|
import std/tables
|
|
import results, chronos
|
|
|
|
import logos_delivery/api/types
|
|
import logos_delivery/channels/reliable_channel_manager
|
|
import logos_delivery/channels/reliable_channel
|
|
|
|
proc send*(
|
|
self: ReliableChannelManager,
|
|
channelId: ChannelId,
|
|
appPayload: seq[byte],
|
|
ephemeral: bool = false,
|
|
): Future[Result[RequestId, string]] {.async: (raises: []).} =
|
|
## Spec-level entry point. Looks the channel up by id and delegates
|
|
## to `ReliableChannel.send`, which exposes the visible pipeline
|
|
## segmentation -> sds -> encryption -> dispatch.
|
|
let chn = self.channels.getOrDefault(channelId)
|
|
if chn.isNil():
|
|
return err("unknown channel: " & channelId)
|
|
return await chn.send(appPayload, ephemeral)
|