Zusammenfassung

  • MESSAGELIMIT begrenzt die Zahl der Nachrichten pro Befehl, nicht die Größe des Postfachs. Bei einer Teilantwort verarbeitet der Server von hohen zu niedrigen UIDs und nennt die niedrigste erreichte UID.
  • COPY und MULTIAPPEND bleiben atomar und führen bei Überschreitung nichts aus; FETCH, SEARCH, STORE, MOVE und UID EXPUNGE können dagegen echte Teilresultate oder Teilwirkungen mit OK hinterlassen.
  • Vollständigkeit entsteht erst durch befehlsspezifische Fortsetzung und Abgleich unter derselben UIDVALIDITY, nicht durch das Capability-Token oder den letzten grünen Status.

Bei UID COPY über dreitausend Nachrichten lautet die Antwort NO [MESSAGELIMIT …]. Keine Nachricht wurde kopiert. Bei UID MOVE über dieselbe Population kann der Server die höchsten tausend UIDs bereits ins Ziel kopiert und aus der Quelle entfernt haben, bevor er OK [MESSAGELIMIT …] sendet.

Wer beide Ereignisse als „Limit überschritten“ speichert, verliert die wichtigste Information. Im ersten Fall ist die Ausgangslage unverändert. Im zweiten müssen Quelle, Ziel und Restmenge zusammengeführt werden. Die Zahl ist identisch; die Wirkung ist es nicht.

Die Grenze gehört zu einem Aufruf

Mit MESSAGELIMIT=N kündigt der Server die maximale Nachrichtenmenge für SEARCH, FETCH, STORE, COPY, MOVE und deren UID-Varianten sowie APPEND und UID EXPUNGE an. SAVELIMIT=N bezeichnet die engere Variante, in der nur COPY und APPEND begrenzt werden. Der angekündigte Wert soll nicht unter tausend liegen.

N ist keine Postfachgröße, kein Speicherquota, keine Aufbewahrungsdauer und keine maximale Nachrichtengröße. Es ist ein Arbeitsbudget für einen Befehl.

Bei SEARCH zählen die untersuchten Nachrichten, nicht bloß die Treffer. Wenn der Server tausend Nachrichten prüft und neun findet, sind diese neun korrekt. Sie sind aber keine Aussage über ältere, noch nicht geprüfte Nachrichten. Ein daraus berechneter Gesamtwert hat einen falschen Nenner.

Gibt der Server den Response Code zurück, muss er von der höchsten zur niedrigsten UID arbeiten. LastUID ist die niedrigste UID dieses Durchlaufs. Sie hilft bei der nächsten Grenze, ist aber weder Restzählung noch Snapshot. Zwischen den Aufrufen können Nachrichten eintreffen oder expunged werden. Ändert sich UIDVALIDITY, gehört die alte Marke zu einer anderen UID-Generation.

OK bestätigt eine Teilwirkung

FETCH kann Daten für die jüngsten tausend Nachrichten liefern und mit OK enden. SEARCH kann die Treffer dieser untersuchten Schicht zurückgeben. STORE kann Flags bereits verändert haben. MOVE kann Nachrichten im Ziel erzeugt und aus der Quelle entfernt haben. UID EXPUNGE kann markierte Nachrichten endgültig beseitigt haben.

Das sind keine unverbindlichen Vorschauen. Der Aufruf ist für den ausgeführten Teil erfolgreich. Gleichzeitig bleibt der ursprünglich angeforderte Umfang offen. Ein einziges Erfolgsfeld kann beide Tatsachen nicht darstellen.

Auch die Fortsetzung unterscheidet sich. Bei UID STORE muss der nächste UID-Bereich die gemeldete niedrigste UID ausschließen. UID MOVE darf dieselbe UID-Menge erneut verwenden, weil bereits verschobene Nachrichten aus der Quelle verschwunden sind. MOVE mit Sequenznummern muss nach den Expunges neu berechnet werden. UID EXPUNGE kann denselben UID-Parameter wiederholen, bis der Limit-Code ausbleibt oder ein NO beziehungsweise BAD folgt.

Ein allgemeiner Retry-Mechanismus genügt nicht. Er muss wissen, ob sein Cursor eine UID oder eine veränderliche Sequenzposition bezeichnet, welche UIDs bereits Wirkung zeigen und weshalb der nächste Befehl weder doppelt noch lückenhaft ist.

Der Limit-Hinweis kann außerdem außerhalb der letzten Zeile stehen. Muss der Server zugleich EXPUNGEISSUED melden, erscheint dieses im tagged OK; MESSAGELIMIT wird in einem untagged NO übertragen. Ein Parser, der nur den Abschlussstatus auswertet, verwirft den offenen Rest. Tag, alle untagged Responses, Daten, Response Codes und Abschlussstatus bilden gemeinsam den Beleg.

Drei Wirkungsklassen statt eines Fehlercodes

COPY und UID COPY sind atomar. Ein zu großer Satz wird mit NO abgewiesen, ohne eine Nachricht zu kopieren. MULTIAPPEND folgt demselben Alles-oder-nichts-Vertrag; eine zu große Gruppe darf nicht teilweise angehängt werden.

MOVE muss nicht atomar sein. STORE und UID EXPUNGE dürfen ebenfalls Teilwirkungen hinterlassen. Daneben stehen EXPUNGE, CLOSE und STATUS UNSEEN, auf die der Server dieses Nachrichtenlimit gar nicht anwenden darf.

Für den Betrieb ergeben sich daher drei Klassen: atomare Ablehnung ohne Wirkung; erfolgreiche Teilausführung mit offener Fortsetzung; vollständiger Befehlsumfang außerhalb dieses Limits. Der Status allein bestimmt die Klasse nicht.

Auch ein vollständiger IMAP-Befehl beweist nur sein Protokollergebnis. Er belegt nicht automatisch dauerhafte Speicherung, Synchronisierung eines anderen Clients oder Anzeige beim Benutzer.

RFC 9394 PARTIAL zieht eine benachbarte Linie. Fordert der Client ausdrücklich eine PARTIAL-Spanne größer als N an, verweigert der Server die Arbeit vollständig. Ohne PARTIAL kann ein vergleichbarer FETCH eine implizite Teilschicht liefern. Eine ausdrücklich bestellte Seite und ein serverseitig erzwungener Schnitt haben unterschiedliche Fehler- und Wirkungsregeln.

Gespeicherte Suche, gespeicherte Lücke

SEARCHRES kann ein Suchergebnis in $ ablegen. Trifft die Quellsuche auf MESSAGELIMIT, muss auch der gespeicherte Satz gekürzt werden. $ bezeichnet dann die gültigen Treffer der untersuchten Schicht, nicht alle Treffer der ursprünglichen Anfrage.

Ein späteres STORE oder COPY auf $ kann vollständig erfolgreich sein und keinen neuen Limit-Hinweis enthalten. Sein Eingabesatz bleibt dennoch unvollständig. Eine korrekte spätere Operation repariert die frühere Abdeckung nicht.

Deshalb braucht ein gespeicherter Satz Herkunftsdaten: Postfach, UIDVALIDITY, ursprüngliche Suchkriterien, angefragter Bereich, Limit, niedrigste verarbeitete UID, Zeitpunkt und Fortsetzungsstatus. Ohne diese Angaben wird ein praktischer Handle zur unbegründeten Vollständigkeitsbehauptung.

UIDAFTER und UIDBEFORE erleichtern den nächsten Suchabschnitt. Sie sperren das Postfach nicht, stellen gelöschte UIDs nicht wieder her und überbrücken keinen Generationswechsel. Sie formulieren Bereiche; sie schaffen keine Transaktion über mehrere Befehle.

Ein angekündigtes Limit kann zunächst weich sein

RFC 9738 beschreibt offen, was strikte Einführung für alte Clients bedeutet. In großen Postfächern sehen sie womöglich nur die neuesten N Nachrichten, liefern falsche SEARCH-Zahlen oder scheitern bei COPY. Aus Sicht des Benutzers fehlen Inhalte oder der Server wirkt defekt.

Als Übergang kann der Server den Wert zunächst ankündigen, ohne ihn durchzusetzen. Unterstützende Clients senden kleinere Befehle und senken die Last. Alte Clients funktionieren weiter. Später kann der Server tausend als weiche Grenze ankündigen, aber erst bei einer nicht veröffentlichten harten Grenze von zehntausend abschneiden. Überschreitungen werden protokolliert, um Anpassung zu beobachten.

Das Capability-Token ist somit eine Koordinationsangabe, keine Messung strikter Durchsetzung. MESSAGELIMIT=1000 belegt, welchen Wert ein informierter Client beachten soll. Ob der Server heute exakt dort schneidet, zeigt erst sein Verhalten. Ob Clients angepasst sind, zeigen ihre Befehlsgrößen und Fortsetzungen.

Angekündigte und harte Grenze müssen getrennte Felder bleiben. Ein Aufruf über tausend kann ein geduldeter Altclient, ein ignorierender neuer Client oder Verkehr vor der scharfen Umschaltung sein. Eine gemeinsame Kategorie „Verstoß“ beseitigt die Grundlage für eine sichere Migrationsentscheidung.

Auftrag und Wirkung zusammenhalten

Ein postfachweiter Job beginnt mit seiner beabsichtigten Population. Für jeden Durchlauf gehören Postfach, UIDVALIDITY, Befehl, angefragter Satz, Wirkungsklasse, beobachtete Capability, zurückgegebene UIDs, tatsächliche Änderungen, untagged Responses, Abschlussstatus, Limit und LastUID ins Protokoll.

Beim Abschluss werden mindestens vier Mengen abgeglichen: zu Beginn beabsichtigte Nachrichten; tatsächlich geprüfte oder veränderte Nachrichten; während der Serie verschwundene Nachrichten; danach eingetroffene Nachrichten außerhalb des ursprünglichen Umfangs. Unerklärte Differenzen bleiben offen. Ein letzter Aufruf ohne Limit-Code macht das dynamische Postfach nicht rückwirkend statisch.

UIDBATCHES plant begrenzte UID-Bereiche. PARTIAL fordert eine bestimmte Seite. MESSAGELIMIT meldet eine während der Ausführung getroffene Grenze. SEARCHRES speichert eine Population. QRESYNC verfolgt Veränderungen. Das Wort „Batch“ darf diese verschiedenen Zeitpunkte nicht verdecken.

RFC 9738 liefert keinen einfacheren Erfolgsbegriff. Es liefert einen genaueren: Dieser Aufruf war erfolgreich, diese Wirkung ist eingetreten, und dieser Rest braucht noch eine Entscheidung. Jede Fortsetzung muss Auftrag und Wirkung zusammenhalten, bis die Differenz geschlossen oder ausdrücklich als offen erklärt ist.

Quellen