E-mail sending yuno. It speaks native SMTPS (implicit TLS, RFC 8314) and queues outgoing messages with TimeRanger2 persistence so they survive transient SMTP outages and yuno restarts. Builds fully static since 7.4.3.
Architecture¶
C_EMAILSENDER <- queueing, retry, dead-letter, MIME encoding
> C_SMTP_SESSION <- SMTP client FSM (banner/EHLO/AUTH/MAIL/RCPT/DATA)
> C_TCP <- smtps://host:465 (implicit TLS from byte zero)C_EMAILSENDERowns two persistent queues on TimeRanger2:emails_queue(pending) andemails_failed(dead-letter). It builds the full RFC 5322 / MIME message (mime_encoder.c) and drives the send/retry loop.C_SMTP_SESSIONimplements the line-based SMTP client as an FSM. It uses AUTH PLAIN; STARTTLS is not implemented (the transport is TLS from the first byte via thesmtps://C_TCP bottom). EHLO advertises the local hostname. An idle session closed by the server (SMTP 421 — OVH does this aggressively) is treated as a graceful close; C_TCP reconnects on the next send.
Configuration¶
Effective config is the usual merge of main.c fixed/variable config with the
external JSON; inspect it at runtime with
ycommand command-yuno id=<id> service=__yuno__ command=view-config.
| Attribute | Default | Purpose |
|---|---|---|
url | (required) | SMTP server, e.g. smtps://ssl0.ovh.net:465 |
from | (required) | Default envelope/From address |
from_beautiful | "" | Optional display name for the From header |
username / password | "" | AUTH PLAIN credentials (empty → skip AUTH) |
timeout_dequeue | 10 | ms between queue polls |
max_retries | 4 | Max total send attempts before dead-lettering |
disable_alarm_emails | false | Drop “ALERT Queuing” alarm emails |
tranger_path / tranger_database | TimeRanger2 store location | |
topic_emails_queue | emails_queue | Pending-queue topic |
topic_emails_failed | emails_failed | Dead-letter topic |
backup_queue_size | 1000000 | Backup the queue topic at this size |
C_SMTP_SESSION adds timeout_response (default 30000 ms) — the per-command
watchdog while waiting for a server reply.
Commands¶
| Command | Parameters | Description |
|---|---|---|
send-email | to, subject, body, reply-to, attachment, inline_file_id, is_html | Enqueue an email. to/cc/bcc accept comma- or semicolon-separated lists; recipients are deduplicated. |
enable-alarm-emails | — | Re-enable alarm emails |
disable-alarm-emails | — | Suppress “ALERT Queuing” alarm emails |
help | cmd, level | Command help |
Other yunos send mail by publishing EV_SEND_EMAIL to the emailsender
service (e.g. logcenter’s summary report).
Delivery semantics¶
Outgoing messages are held in the persistent emails_queue and are never
dropped while waiting:
A message is only dispatched while the SMTP session is connected and authenticated. If the server is down, the URL is wrong, or credentials are rejected, the message stays in the queue.
C_TCPkeeps reconnecting on its own and delivery resumes once the link is back — nothing is dead-lettered just because the link is momentarily unavailable.The body is persisted as part of the queued message (a string), so it survives both retries and a yuno restart.
A message stays at the head of the queue until it is either sent or its attempts are exhausted. A transient send failure (server NACK, connection dropped mid-send) is retried up to
max_retriestotal attempts.When
max_retriesis exhausted — or the message is permanently undeliverable (missing recipient, un-encodable body) — it is moved toemails_failedand removed from the main queue. The dead-letter queue is not retried automatically.
Every outcome is logged: a warning per retry, an error when a message is moved to the dead-letter queue, and an info line on success.
Debugging¶
Trace levels (enable with
ycommand command-yuno id=<id> service=__yuno__ command=set-gclass-trace gclass=<G> set=1 level=<L>):
| GClass | Level | Shows |
|---|---|---|
C_EMAILSENDER | messages | The MIME message dispatched to the SMTP child |
C_SMTP_SESSION | smtp | SMTP FSM phases — commands sent (>>>) and reply codes (<<<) |
C_SMTP_SESSION | traffic | Raw bytes in/out (hex dump) |