Files
jcoffey-dev 11960a6ac8 IMAP: run at most four operations per session and keep writes in order
Every IMAP command after sign-in started its own task with no limit, so a
signed-in client could pipeline a burst of commands and have the server
start as many tasks at once as the burst held, bounded only by the
per-account request rate. The tasks also ran side by side whatever they
did: an APPEND into a mailbox created by the CREATE just before it failed
with TRYCREATE, a STATUS or FETCH sent after an APPEND or STORE could miss
its result, and an EXPUNGE could run while an earlier COPY was still
reading the messages.

Each session now has a gate of four permits. A command that only reads
(FETCH without marking messages seen, SEARCH, SORT, THREAD, STATUS, LIST,
GETACL, MYRIGHTS, GETQUOTA) takes one; a command that changes the account
or the session (APPEND, COPY, MOVE, STORE, CREATE, DELETE, RENAME,
SUBSCRIBE, SETACL, a FETCH that sets \Seen, and every command run without
a task of its own, such as SELECT, EXPUNGE and CLOSE) takes all four. So
at most four reads run together, a write starts once everything before it
has finished, and later commands wait for it (RFC 9051, section 5.5). The
session waits for the permit before it starts the command and reads
nothing more from the client meanwhile.

Test: a new imap suite check pipelines CREATE, eight APPENDs and STATUS in
one write; on main the APPENDs failed with TRYCREATE before the CREATE
completed and STATUS saw no mailbox, now all complete in order and STATUS
reports 8; it also pipelines STORE then FETCH. Unit tests of the gate
check the bound and that a write never overlaps another operation.
2026-10-29 06:09:09 -07:00
..