From 67eec35c0710a06a7f359a19cd1e3b0d708afbbe Mon Sep 17 00:00:00 2001
From: Wietse Venema
Topics covered by this document:
+From the start, Postfix has used a simple but robust algorithm where the per-destination delivery concurrency is decremented by 1 -after a delivery suffered connection or handshake failure, and +after delivery failed due to connection or handshake failure, and incremented by 1 otherwise. Of course the concurrency is never allowed to exceed the maximum per-destination concurrency limit. And when a destination's concurrency level drops to zero, the @@ -282,7 +284,8 @@ argument to the listen(2) system call, and "postfix reload" does not re-issue this call.
@@ -529,7 +532,12 @@ with increasing concurrency. See text for a discussion of results.All results in the previous sections are based on the first delivery runs only; they do not include any second etc. delivery -attempts. The first two examples show that the effect of feedback +attempts. It's also worth noting that the measurements look at +steady-state behavior only. They don't show what happens when the +client starts sending at a much higher or lower concurrency. +
+ +The first two examples show that the effect of feedback is negligible when concurrency is limited due to congestion. This is because the initial concurrency is already at the client's concurrency maximum, and because there is 10-100 times more positive @@ -548,6 +556,20 @@ the next section.
Limitations of less-than-1 per delivery feedback
+Less-than-1 feedback is of interest primarily when sending large +amounts of mail to destinations with active concurrency limiters +(servers that reply with 421, or firewalls that send RST). When +sending small amounts of mail per destination, less-than-1 per-delivery +feedback won't have a noticeable effect on the per-destination +concurrency, because the number of deliveries to the same destination +is too small. You might just as well use zero per-delivery feedback +and stay with the initial per-destination concurrency. And when +mail deliveries fail due to congestion instead of active concurrency +limiters, the measurements above show that per-delivery feedback +has no effect. With large amounts of mail you might just as well +use zero per-delivery feedback and start with the maximal per-destination +concurrency.
+The scheduler with less-than-1 concurrency feedback per delivery solves a problem with servers that have active concurrency limiters. This works only because feedback is handled @@ -582,8 +604,8 @@ delivery (no connect or handshake error), and use an equal or smaller amount of negative feedback per "bad" delivery. The downside of using concurrency-independent feedback is that some of the old +/-1 feedback problems will return at large concurrencies. Sites that -deliver at non-trivial per-destination concurrencies will require -special configuration.
+must deliver mail at non-trivial per-destination concurrencies will +require special configuration.Concurrency configuration parameters
@@ -643,7 +665,7 @@ activity-This document attempts to describe the new queue manager and its +The following sections describe the new queue manager and its preemptive scheduler algorithm. Note that the document was originally written to describe the changes between the new queue manager (in this text referred to as nqmgr, the name it was known by @@ -1776,7 +1798,8 @@ with per-domain FIFO scheduling, and per-delivery +/-1 concurrency feedback.
Patrik Rak designed and implemented preemption where mail with -fewer recipients can slip past mail with more recipients. +fewer recipients can slip past mail with more recipients in a +controlled manner, and wrote up its documentation. Wietse Venema initiated a discussion with Patrik Rak and Victor Duchovni on alternatives for the +/-1 feedback scheduler's aggressive @@ -1788,10 +1811,10 @@ feedback and dead site detection. context of concurrency-limited servers. Wietse Venema then re-designed the concurrency scheduler in -terms of simplest possible concepts: less-than-1 concurrency feedback -per delivery, forward and reverse concurrency feedback hysteresis, -and pseudo-cohort failure. At this same time, concurrency feedback -was separated from dead site detection. +terms of the simplest possible concepts: less-than-1 concurrency +feedback per delivery, forward and reverse concurrency feedback +hysteresis, and pseudo-cohort failure. At this same time, concurrency +feedback was separated from dead site detection. These simplifications, and their modular implementation, helped to develop further insights into the different roles that positive diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index a3df159e6..91aa69b43 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -3278,8 +3278,7 @@ Examples: The initial per-destination concurrency level for parallel delivery -to the same destination. This limit applies to delivery via smtp(8), -and via the pipe(8) and virtual(8) delivery agents. +to the same destination. With per-destination recipient limit > 1, a destination is a domain, otherwise it is a recipient.
diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index e56ee0512..31d55efce 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -1829,8 +1829,7 @@ inet_protocols = ipv4, ipv6 .ft R .SH initial_destination_concurrency (default: 5) The initial per-destination concurrency level for parallel delivery -to the same destination. This limit applies to delivery via \fBsmtp\fR(8), -and via the \fBpipe\fR(8) and \fBvirtual\fR(8) delivery agents. +to the same destination. With per-destination recipient limit > 1, a destination is a domain, otherwise it is a recipient. .PP diff --git a/postfix/proto/SCHEDULER_README.html b/postfix/proto/SCHEDULER_README.html index 537b27937..8e35f8122 100644 --- a/postfix/proto/SCHEDULER_README.html +++ b/postfix/proto/SCHEDULER_README.html @@ -26,17 +26,19 @@ deliveries at specific times, and removes mail from the queue after the last delivery attempt. There are two major classes of mechanisms that control the operation of the queue manager. +Topics covered by this document:
+-
@@ -97,7 +99,7 @@ concurrency scheduler- Concurrency scheduling is concerned +
- Concurrency scheduling, concerned with the number of concurrent deliveries to a specific destination, including decisions on when to suspend deliveries after persistent failures. -
- Preemptive scheduling is concerned with +
- Preemptive scheduling, concerned with the selection of email messages and recipients for a given destination. -
- Credits . This document would not be +
- Credits, something this document would not be complete without.
From the start, Postfix has used a simple but robust algorithm where the per-destination delivery concurrency is decremented by 1 -after a delivery suffered connection or handshake failure, and +after delivery failed due to connection or handshake failure, and incremented by 1 otherwise. Of course the concurrency is never allowed to exceed the maximum per-destination concurrency limit. And when a destination's concurrency level drops to zero, the @@ -282,7 +284,8 @@ argument to the listen(2) system call, and "postfix reload" does not re-issue this call.
Mail was discarded with "local_recipient_maps = static:all" and -"local_transport = discard". The discard action in header/body checks +"local_transport = discard". The discard action in access maps or +header/body checks could not be used as it fails to update the in_flow_delay counters. @@ -468,7 +471,7 @@ a server concurrency limit and a client initial destination concurrency of 5, and a server process limit of 10; all other conditions were the same as with the first measurement. The same result would be obtained with a FreeBSD or Linux server, because the "pushing back" -is done entirely by the receiving Postfix. +is done entirely by the receiving side. @@ -529,7 +532,12 @@ with increasing concurrency. See text for a discussion of results.All results in the previous sections are based on the first delivery runs only; they do not include any second etc. delivery -attempts. The first two examples show that the effect of feedback +attempts. It's also worth noting that the measurements look at +steady-state behavior only. They don't show what happens when the +client starts sending at a much higher or lower concurrency. +
+ +The first two examples show that the effect of feedback is negligible when concurrency is limited due to congestion. This is because the initial concurrency is already at the client's concurrency maximum, and because there is 10-100 times more positive @@ -548,6 +556,20 @@ the next section.
Limitations of less-than-1 per delivery feedback
+Less-than-1 feedback is of interest primarily when sending large +amounts of mail to destinations with active concurrency limiters +(servers that reply with 421, or firewalls that send RST). When +sending small amounts of mail per destination, less-than-1 per-delivery +feedback won't have a noticeable effect on the per-destination +concurrency, because the number of deliveries to the same destination +is too small. You might just as well use zero per-delivery feedback +and stay with the initial per-destination concurrency. And when +mail deliveries fail due to congestion instead of active concurrency +limiters, the measurements above show that per-delivery feedback +has no effect. With large amounts of mail you might just as well +use zero per-delivery feedback and start with the maximal per-destination +concurrency.
+The scheduler with less-than-1 concurrency feedback per delivery solves a problem with servers that have active concurrency limiters. This works only because feedback is handled @@ -582,8 +604,8 @@ delivery (no connect or handshake error), and use an equal or smaller amount of negative feedback per "bad" delivery. The downside of using concurrency-independent feedback is that some of the old +/-1 feedback problems will return at large concurrencies. Sites that -deliver at non-trivial per-destination concurrencies will require -special configuration.
+must deliver mail at non-trivial per-destination concurrencies will +require special configuration.Concurrency configuration parameters
@@ -643,7 +665,7 @@ activity-This document attempts to describe the new queue manager and its +The following sections describe the new queue manager and its preemptive scheduler algorithm. Note that the document was originally written to describe the changes between the new queue manager (in this text referred to as nqmgr, the name it was known by @@ -1776,7 +1798,8 @@ with per-domain FIFO scheduling, and per-delivery +/-1 concurrency feedback.
Patrik Rak designed and implemented preemption where mail with -fewer recipients can slip past mail with more recipients. +fewer recipients can slip past mail with more recipients in a +controlled manner, and wrote up its documentation. Wietse Venema initiated a discussion with Patrik Rak and Victor Duchovni on alternatives for the +/-1 feedback scheduler's aggressive @@ -1788,10 +1811,10 @@ feedback and dead site detection. context of concurrency-limited servers. Wietse Venema then re-designed the concurrency scheduler in -terms of simplest possible concepts: less-than-1 concurrency feedback -per delivery, forward and reverse concurrency feedback hysteresis, -and pseudo-cohort failure. At this same time, concurrency feedback -was separated from dead site detection. +terms of the simplest possible concepts: less-than-1 concurrency +feedback per delivery, forward and reverse concurrency feedback +hysteresis, and pseudo-cohort failure. At this same time, concurrency +feedback was separated from dead site detection. These simplifications, and their modular implementation, helped to develop further insights into the different roles that positive diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index 9902af955..b81932523 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -1859,8 +1859,7 @@ inet_protocols = ipv4, ipv6 The initial per-destination concurrency level for parallel delivery -to the same destination. This limit applies to delivery via smtp(8), -and via the pipe(8) and virtual(8) delivery agents. +to the same destination. With per-destination recipient limit > 1, a destination is a domain, otherwise it is a recipient.
diff --git a/postfix/src/global/deliver_request.h b/postfix/src/global/deliver_request.h index 8c07e0209..2c74c00f7 100644 --- a/postfix/src/global/deliver_request.h +++ b/postfix/src/global/deliver_request.h @@ -69,14 +69,15 @@ typedef struct DELIVER_REQUEST { #define DEL_REQ_FLAG_MTA_VRFY (1<<8) /* MTA-requested address probe */ #define DEL_REQ_FLAG_USR_VRFY (1<<9) /* user-requested address probe */ #define DEL_REQ_FLAG_RECORD (1<<10) /* record and deliver */ -#define DEL_REQ_FLAG_SCACHE_LD (1<<11) /* Consult opportunistic cache */ -#define DEL_REQ_FLAG_SCACHE_ST (1<<12) /* Update opportunistic cache */ +#define DEL_REQ_FLAG_CONN_LOAD (1<<11) /* Consult opportunistic cache */ +#define DEL_REQ_FLAG_CONN_STORE (1<<12) /* Update opportunistic cache */ /* - * Cache Load and Store as value or mask. Use explicit names for multi-bit + * Cache Load and Store as value or mask. Use explicit _MASK for multi-bit * values. */ -#define DEL_REQ_FLAG_SCACHE_MASK (DEL_REQ_FLAG_SCACHE_LD|DEL_REQ_FLAG_SCACHE_ST) +#define DEL_REQ_FLAG_CONN_MASK \ + (DEL_REQ_FLAG_CONN_LOAD | DEL_REQ_FLAG_CONN_STORE) /* * For compatibility, the old confusing names. diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index def7a4d99..6259379e1 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20071213" +#define MAIL_RELEASE_DATE "20071215" #define MAIL_VERSION_NUMBER "2.5" #ifdef SNAPSHOT diff --git a/postfix/src/oqmgr/qmgr_entry.c b/postfix/src/oqmgr/qmgr_entry.c index 225e09213..b37394c77 100644 --- a/postfix/src/oqmgr/qmgr_entry.c +++ b/postfix/src/oqmgr/qmgr_entry.c @@ -138,12 +138,12 @@ QMGR_ENTRY *qmgr_entry_select(QMGR_QUEUE *queue) * prevents unnecessary session caching when we have a burst of mail * <= the initial concurrency limit. */ - if ((queue->dflags & DEL_REQ_FLAG_SCACHE_ST) == 0) { + if ((queue->dflags & DEL_REQ_FLAG_CONN_STORE) == 0) { if (BACK_TO_BACK_DELIVERY()) { if (msg_verbose) msg_info("%s: allowing on-demand session caching for %s", myname, queue->name); - queue->dflags |= DEL_REQ_FLAG_SCACHE_MASK; + queue->dflags |= DEL_REQ_FLAG_CONN_MASK; } } @@ -158,7 +158,7 @@ QMGR_ENTRY *qmgr_entry_select(QMGR_QUEUE *queue) if (msg_verbose) msg_info("%s: disallowing on-demand session caching for %s", myname, queue->name); - queue->dflags &= ~DEL_REQ_FLAG_SCACHE_ST; + queue->dflags &= ~DEL_REQ_FLAG_CONN_STORE; } } } diff --git a/postfix/src/qmgr/qmgr_entry.c b/postfix/src/qmgr/qmgr_entry.c index 9e10a21ff..9f89e0a73 100644 --- a/postfix/src/qmgr/qmgr_entry.c +++ b/postfix/src/qmgr/qmgr_entry.c @@ -150,12 +150,12 @@ QMGR_ENTRY *qmgr_entry_select(QMGR_PEER *peer) * prevents unnecessary session caching when we have a burst of mail * <= the initial concurrency limit. */ - if ((queue->dflags & DEL_REQ_FLAG_SCACHE_ST) == 0) { + if ((queue->dflags & DEL_REQ_FLAG_CONN_STORE) == 0) { if (BACK_TO_BACK_DELIVERY()) { if (msg_verbose) msg_info("%s: allowing on-demand session caching for %s", myname, queue->name); - queue->dflags |= DEL_REQ_FLAG_SCACHE_MASK; + queue->dflags |= DEL_REQ_FLAG_CONN_MASK; } } @@ -170,7 +170,7 @@ QMGR_ENTRY *qmgr_entry_select(QMGR_PEER *peer) if (msg_verbose) msg_info("%s: disallowing on-demand session caching for %s", myname, queue->name); - queue->dflags &= ~DEL_REQ_FLAG_SCACHE_ST; + queue->dflags &= ~DEL_REQ_FLAG_CONN_STORE; } } } diff --git a/postfix/src/qmqpd/qmqpd.c b/postfix/src/qmqpd/qmqpd.c index c73a7d59e..dab3b09dc 100644 --- a/postfix/src/qmqpd/qmqpd.c +++ b/postfix/src/qmqpd/qmqpd.c @@ -802,6 +802,7 @@ int main(int argc, char **argv) single_server_main(argc, argv, qmqpd_service, MAIL_SERVER_TIME_TABLE, time_table, MAIL_SERVER_STR_TABLE, str_table, + MAIL_SERVER_BOOL_TABLE, bool_table, MAIL_SERVER_PRE_INIT, pre_jail_init, MAIL_SERVER_PRE_ACCEPT, pre_accept, MAIL_SERVER_POST_INIT, post_jail_init, diff --git a/postfix/src/smtp/smtp_connect.c b/postfix/src/smtp/smtp_connect.c index 6b7582b0d..f8ec4fdcc 100644 --- a/postfix/src/smtp/smtp_connect.c +++ b/postfix/src/smtp/smtp_connect.c @@ -457,9 +457,9 @@ static void smtp_cache_policy(SMTP_STATE *state, const char *dest) if (smtp_cache_dest && string_list_match(smtp_cache_dest, dest)) { state->misc_flags |= SMTP_MISC_FLAG_CONN_CACHE_MASK; } else if (var_smtp_cache_demand) { - if (request->flags & DEL_REQ_FLAG_SCACHE_LD) + if (request->flags & DEL_REQ_FLAG_CONN_LOAD) state->misc_flags |= SMTP_MISC_FLAG_CONN_LOAD; - if (request->flags & DEL_REQ_FLAG_SCACHE_ST) + if (request->flags & DEL_REQ_FLAG_CONN_STORE) state->misc_flags |= SMTP_MISC_FLAG_CONN_STORE; } }