use relay's maxsmtprecipients metadata for smtp chunking, to remove another is_chatmail use#8426
use relay's maxsmtprecipients metadata for smtp chunking, to remove another is_chatmail use#8426hpk42 wants to merge 4 commits into
Conversation
…hunking to smtp loop
| pub(crate) async fn get_max_smtp_rcpt_to(&self) -> Result<usize> { | ||
| let is_chatmail = self.is_chatmail().await?; | ||
| let metadata_limit = self | ||
| .metadata |
There was a problem hiding this comment.
self here is a Context, so this metadata is not per-transport and is just the metadata fetched from some server rather than the sending transport.
There was a problem hiding this comment.
uh right. so i guess it's better to have a context.max_smtp_rcpt_to as a transport_id->max_rcpts map and write/read from that? I would like to avoid adding a column to transport sql table (had this in an earlier revision but needs a migration). However, context.max_smtp_rcpt_to could lead to smtp reading it before imap metadata reading filled it for the transport, but worst case it uses 50 recipients chunking for this message. If that trade-off is not acceptable, then i don't see another solution than using a new column for transport table.
sidenote: conceptually it would probably make sense to have context.metadata be transport dependent completely. But that would blow up the PR i am afraid, and is better done in a separate PR.
There was a problem hiding this comment.
Separate map should be fine.
update_metadata has access to self.transport_id, so it can check if the limit was already fetched, but this fetching should be before the early return that is for the case when metadata is already fetched. Ideally the whole metadata should be turned into per-transport map, but then all the code that uses metadata, e.g. iroh relays, needs an update to pick arbitrary (e.g. the first one, should be fine for BTreeMap) transport.
There was a problem hiding this comment.
turned out that making metadata transport dependent actually was much easier than i feared, and even saves a few LOCs in the end. Previously i thought we have to do more to get a metadata value, but indeed just first one is fine. It was last writer and now it's whatever btreemap yields first, both pretty random. b1aefc4
i fixed the comment. Also tried removing the deletion logic but that makes test_mark_message_as_delivered_only_after_sent_out_fully and test_resend_after_ndn fail, so at least the tests exercise it. In reality, smtp-lost-ok case should be rare and sending twice is deduplicated at receiver sides. Cleartext usage (where receivers may not deduplicate) does not really matter for this edge case. |
…d get_configured_provider helper
| /// <https://github.com/deltachat/deltachat-desktop/issues/5447>. | ||
| pub async fn ice_servers(context: &Context) -> Result<String> { | ||
| if let Some(ref metadata) = *context.metadata.read().await { | ||
| if let Some(metadata) = context.metadata.read().await.values().next() { |
There was a problem hiding this comment.
TODO for the future: this may collect all ICE servers, maybe using multiple TURN servers at once makes the calls more reliable.
| )?; | ||
| for recipients_chunk in recipients.chunks(chunk_size) { | ||
| let recipients_chunk = recipients_chunk.join(" "); | ||
| if !recipients.is_empty() { |
There was a problem hiding this comment.
This if can be moved above, before t.prepare(), to skip preparing the statement that is not used afterwards.
|
|
||
| /// Returns maximum number of recipients the provider allows to send a single email to. | ||
| /// Returns maximum number of recipients a single email can be sent to. | ||
| pub(crate) async fn get_max_smtp_rcpt_to(&self) -> Result<usize> { |
There was a problem hiding this comment.
Type can be changed to return u32 to avoid conversions (especially as which is not well-defined). It's anyway bad idea to use usize in the logic, the rare exception is buffer sizes. usize is accidentally 32 bit on old android phones that are still supported while everything is tested on 64-bit platforms.
| } | ||
| "/shared/vendor/deltachat/maxsmtprecipients" => { | ||
| if let Some(value) = m.value { | ||
| if let Ok(limit) = value.parse() { |
There was a problem hiding this comment.
Better use u32::try_from, see https://github.com/chatmail/core/blob/main/STYLE.md#do-not-use-into-try_into-or-parse
Relays since chatmail/relay#960 and released mid may with relay-1.11 set maxsmtprcipients imap metadata to 1000. I manually verified that nine.testrun.org, mailchat.pl and a few others have it set already.
this PR also moves recipient chunking to smtp loop where it belongs because it's transport specific.