Commit Graph
865 Commits
Author SHA1 Message Date
Wez Furlong ed8aa53d55 Add RocksDB as a spool option
Looks pretty good compared to Sled.

|kind         | flush | throughput |
+-------------+-------+------------+
|RocksDB      | false | 102mm/hr   |
|RocksDB      | true  | 96mm/hr    | *
|Sled         | false | 96mm/hr    |
|Sled         | true  | 34mm/hr    |
|LocalDisk    | false | 24mm/hr    |
|LocalDisk    | true  | 1mm/hr     |

These numbers are from a 5950x (32 core) with an nvme drive,
as reported by:

```
cargo run --release -p traffic-gen -- --target 127.0.0.1:2025 --duration 20 --concurrency 16024
```

Note that the flush implementation with rocksdb just adjusts the setting
of use_fsync when opening the database.

There is an explicit db-wide flush that can be called, but it is very
aggressive and thorougly tanks performance down to 0.25mm/hr.

Note as well that rocksdb has a number of configuration options that may
work better as a write-once spool than the currently selected defaults;
more analysis could be done, but at the time of writing this commit
message, the defaults are the best performing storage option and going
further isn't a priority.
2023-02-20 23:04:01 -07:00
Wez Furlong 973a3b6f10 spool: add Sled as an alternative local spool
Add a `kind` and `flush` fields when defining a spool.  Add a new
[sled](https://docs.rs/sled/latest/sled/index.html) based spool
implementation.

Initial benchmarking, especially at high concurrency, shows
promising numbers:

|kind         | flush | throughput |
+-------------+-------+------------+
|Sled         | false | 96mm/hr    |
|Sled         | true  | 34mm/hr    |
|LocalDisk    | false | 24mm/hr    |
|LocalDisk    | true  | 1mm/hr     |

These numbers are from a 5950x (32 core) with an nvme drive,
as reported by:

```
cargo run --release -p traffic-gen -- --target 127.0.0.1:2025 --duration 20 --concurrency 16024
```

What's the catch? sled is considered beta by its authors.
https://github.com/spacejam/sled#known-issues-warnings
2023-02-20 22:08:05 -07:00
Wez Furlong aa70b4ab23 spool: revise how we split uuid into directory components
This should give a better distribution and result in fewer
directories overall
2023-02-20 19:46:28 -07:00
Wez Furlong c049277d61 parallelize writing spool and metadata when saving the message 2023-02-20 18:21:24 -07:00
Wez Furlong d944246595 remove a bottleneck, add deferred spool mode
During DATA, spawn the queue resolve and insertion into a separate
task so that we can respond to the injection with lower latency.
2023-02-20 13:52:04 -07:00
Wez Furlong 002d9f94dd traffic-gen: adjust waiting strategy
At very high concurrency we can get a bit stuck waiting for
the tasks to finish.

Adjust so that we wait for the desired duration and sample the
count at that point, then we'll proceed to report that without
worrying about joining the sender tasks.
2023-02-20 12:07:38 -07:00
Wez Furlong 2399495a60 traffic-gen: improve error reporting 2023-02-20 11:15:04 -07:00
Wez Furlong caf47d4c4e add traffic generator 2023-02-20 10:30:58 -07:00
Wez Furlong ca0456a6f7 fix detecting EOF 2023-02-20 10:27:20 -07:00
Wez Furlong d8021a0ebf add redis build with redis-cell 2023-02-20 06:10:20 +00:00
Wez Furlong bda38adf90 restructure docker build bits
This makes it a bit easier to add other docker images
for other things in the future
2023-02-20 02:47:59 +00:00
Wez Furlong 6ebf6762ce may need to load metadata to resolve the queue 2023-02-19 16:53:42 -07:00
Wez Furlong 9149063b57 Add Received header at reception time
Also fix missing CRLFs in message bodies!
2023-02-19 16:49:11 -07:00
Wez Furlong f8fc4582fc add counters for messages in different states 2023-02-19 15:39:51 -07:00
Wez Furlong a8ddc72dee add counters for transient and permanent failures 2023-02-19 12:45:04 -07:00
Wez Furlong 5a8280626b metrics: add connection and msg delivery totals
These counters are monotonic but can be used with eg: prometheus'
rate operator to derive message and connection rates.
2023-02-19 12:25:40 -07:00
Wez Furlong 17e5d7f113 refactor queue insertion logic
more DRY, less likely to miss out on bumping metrics
2023-02-19 12:01:29 -07:00
Wez Furlong 73062ab086 use prometheus directly for metrics
It occurred to me that we don't want to accumulate potentially
millions of per-site metrics forever, and that the `metrics`
crate doesn't provide a way to de-register metrics.

This commit bypasses that layer and goes directly to the prometheus
crate which does provide some nicer accessors that do allow
removing metrics.
2023-02-19 09:48:46 -07:00
Wez Furlong e1e96b3931 tidy up some debug logging 2023-02-19 08:31:21 -07:00
Wez Furlong e07f47a849 spool: improve context in startup debug message 2023-02-19 08:28:17 -07:00
Wez Furlong c0a9ac113d refactor: move smtp listener startup into smtp_server.rs 2023-02-19 08:26:38 -07:00
Wez Furlong 9812eef7ac add prometheus metrics export
This commit adds in an http listener that provides a `/metrics`
endpoint that can be configured as a target by prometheus to
scrape and record metrics.

You may also curl it for yourself.

While playing around with this, I found and fixed a deadlock
in the case that the initial spool in logic found and expired
a message; it would reuse a helper function that wanted to acquire
a lock, but it already held the lock.
2023-02-19 00:17:58 -07:00
Wez Furlong 82944d79f1 fmt 2023-02-18 20:51:37 -07:00
Wez Furlong 1dcc994c9f Add basic docker build 2023-02-19 03:37:06 +00:00
Wez Furlong 20749ddd30 add pipelining support to the smtp client 2023-02-18 18:42:55 -07:00
Wez Furlong d88ae59c5c allow setting tls certificate and key for smtp listener 2023-02-18 18:13:31 -07:00
Wez Furlong 7336481e02 use OnceCell to init tls params once and share them 2023-02-18 18:00:44 -07:00
Wez Furlong e80b0403cb refactor: move tls acceptor to server params 2023-02-18 17:35:40 -07:00
Wez Furlong 54e230ffca message expiration
* Switch uuids to v1 format, so that we can cheaply determine
  when a message was created without having to load its metadata
  from the spool
* Add some message delivery parameters; retry interval, limit, max age
* Respect those parameters when spooling in and when we encounter
  a transient failure.
2023-02-18 14:39:54 -07:00
Wez Furlong 44e4cc2202 timeq: make pop a bit more efficient
Should be closer to O(buckets-with-ready-timers) than the previous
O(milliseconds-to-catchup)
2023-02-18 07:47:06 -07:00
Wez Furlong 086d9008a1 allow configuring the smtp listener banner text 2023-02-18 07:40:01 -07:00
Wez Furlong 667bb91525 formalize tenant/campaign components of default queue naming 2023-02-18 07:28:03 -07:00
Wez Furlong acf36fe010 slightly expand readme and comments 2023-02-17 14:06:56 -07:00
Wez Furlong 054501e535 some basic plumbing for configuring outbound settings
A callback is used to resolve the config at the time that
we set up the destination site structure (eg: when we get the first
ready-to-send message for it, and again after it has idled out).

This is used in the example configs to enable "OpportunisticInsecure"
TLS mode so that we can successfully delivery over TLS to the
default self-signed TLS certs on the sink.
2023-02-17 13:52:34 -07:00
Wez Furlong d889acc275 replace mail-send with our own client implementation
This removes a dep on an AGPL crate
2023-02-17 11:08:59 -07:00
Wez Furlong 42d885ef02 add basic smtp client 2023-02-17 09:44:27 -07:00
Wez Furlong a20e271365 timeq: increase sleeps in the hope of reducing flakiness
The real solution is to not use the real time for these,
but that requires shimming the concept of time.
2023-02-17 06:03:51 -07:00
Wez Furlong 7a9780361a implement starttls using automatic self-signed certs
We can make proper cert+key configurable later
2023-02-16 22:58:46 -07:00
Wez Furlong 03fb1f1cb8 do our own line buffering in preparation for starttls
This also allows us to handle excessive input line length as well.
2023-02-16 22:20:44 -07:00
Wez Furlong 7410cfd1b1 adopt BoxedAsyncReadAndWrite in smtp server
This allows erasing the <T> generic from the smtp server,
which in turn will make it possible to switch up to TLS
in a future commit.
2023-02-16 20:21:17 -07:00
Wez Furlong 135354b140 move AsyncReadAndWrite trait to rfc5321
This is prep for doing some protocol client/server work in this crate.
2023-02-16 20:10:40 -07:00
Wez Furlong 36a84b15bb add relay_hosts config, default to loopback 2023-02-16 19:42:36 -07:00
Wez Furlong dc46a6ad78 advertise pipelining and enhancedstatuscodes extensions 2023-02-16 18:53:53 -07:00
Wez Furlong a710a88db5 cut over smtp server to new command parser 2023-02-16 18:09:55 -07:00
Wez Furlong 01f38f509a format 2023-02-16 16:35:18 -07:00
Wez Furlong f9155541fe Add fuzzer for rfc5321 parser 2023-02-16 16:34:44 -07:00
Wez Furlong c4c206df1e Add rfc5321 protocol parser
This parses commands received by the server.
Can be expanded to responses from a server in the future.
2023-02-16 16:25:17 -07:00
Wez Furlong 8e067ef01e sort mx entries at a given pref by name
This gives a stable order and thus a stable destination site name.

For example:

```
hanmail.net -> MX { exchanges: ["mx4.hanmail.net.", "mx2.hanmail.net.", "mx1.hanmail.net.", "mx3.hanmail.net."], preference: 10 }
```

The MX result from the Resolver sorts groups of hosts by preference
(good!), but the list of exchanges within a given preference level are
in an undefined order.

Sorting the list of exchanges at each priority level gives a consistent
and stable overall ordering.
2023-02-15 18:41:16 -07:00
Wez Furlong 7c9ac797e7 add implicit MX resolution for user@hostname where there is no MX record 2023-02-15 18:11:02 -07:00
Wez Furlong bf87ac53e0 suppress warning with currently unused function 2023-02-15 17:29:54 -07:00