| 5 | We would like to ship out new messages in a timely manner, and also handle retrying failed messages, but avoid unnecessary overhead, and without doing time-consuming sends in request context where they will slow down response to the user. |
| 6 | |
| 7 | Right now, inserting a message in the queue (send_by_pe_id) is unconditionally followed by kicking off the outbound sending task (which runs asynchronously, not in request context). That isn't just making an attempt to send the single new message, but rather processes the entire queue. Messages that are in the queue in order to be retried due to an earlier send failure will be retried along with the one new message. |
| 8 | |
| 9 | To avoid a time hit to users during requests that currently include a message send (currently the known cases are all registration email), we can instead queue up those messages. If we do that, we need to deal with the consequences of sharing the queue between new and retry messages. |
| 10 | |
| 11 | Consider these cases: |
| 12 | |
| 13 | * Email sending is not a common activity for the site -- sends occur less frequently than the periodic task. In that case, kicking off an immediate run of the entire outbound task is not a significant overhead. If the periodic task is set to run infrequently compared to the frequency of new sends, then an immediate run makes entire sense. If new sends are not frequent, this isn't a lot of overhead. |
| 14 | * However, let's say that the site actively uses messaging -- that it's a common event. |
| 15 | * If new sends are significantly more frequently than the periodic task. Now the async runs will dominate, and the periodic task and the site's chosen periodic rate will be irrelevant. The conditions that cause a message to fail and be retained in the queue for retry are unlikely to clear up in a short time, especially if the periodic time was chosen to be appropriate for retries. There will be a lot of overhead just from the task processing and futile retries. |
| 16 | * If sends are common ''and'' the periodic task is scheduled frequently, there would, in fact, be little benefit from launching the queue processing on each send. |
| 17 | |
| 18 | (Dominic points out that if each outbound send processes the entire queue including retries, then causing outbound sends could be used as a DoS attack. That works especially "well" if the sends are sure to fail and become retries.) |