Skip to content

Send windows, quiet periods and client-side throttling #8

Description

@jbagsik

Parent

#1

What to build

Control over when mail leaves, and how fast. Two related things: a send window (working days, times of day, quiet periods during which nothing goes out) and a client-side rate limit per mailer.

Both are jobs, not event handlers. Mail that arrives outside its window is recorded as suppressed rather than sent or dropped, and a scheduled release job picks suppressed mail up once the window opens. The rate limit paces a batch by spacing dispatches, so a queue of several hundred messages drains over minutes instead of hitting a provider limit in one burst.

Client-side pacing is not belt-and-braces here: at least one major provider's documentation is internally inconsistent about what happens when its per-minute message rate is exceeded, so the server's behaviour on breach cannot be relied on.

Configuration is the right home for this ticket, and an operator-facing surface comes separately in #11 — database-backed windows and quiet periods with a Filament resource, layered on what is built here exactly as configuration defaults are overridden by database rows in other Moox packages. Two settings stay in configuration permanently even then: the rate limit, because it describes what the provider tolerates rather than a business decision, and the global off switch, because one mistaken edit in a table would release every held message to real recipients. Note also that a database row is not environment-aware — a production dump restored into staging carries its windows along — which is the underlying reason those two are excluded rather than merely inconvenient.

Acceptance criteria

  • Mail dispatched inside its window sends immediately
  • Mail dispatched during a quiet period is recorded as suppressed and is not lost
  • The scheduled release job sends suppressed mail once the window opens, and the row moves from suppressed to sent
  • Windows are configured as weekdays and times of day, not as intervals
  • A batch larger than the configured rate is paced rather than rejected — asserted by timing or by counting dispatches per interval, not by inspecting internals
  • The rate limit is per mailer, so two mailboxes do not share one budget
  • A suppressed row records why it was withheld
  • Windows and throttling can each be disabled independently by configuration
  • Release and pacing are queued jobs carrying the shared progress trait; no work sits in a listener
  • README documents the configuration in the vocabulary a non-developer would use; CHANGELOG updated

Blocked by

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentSpec is ready for an agent to implement

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions