[FIX] mail.mail: avoid prefetching attachment data in memory while processing mail queue, could fail due to memory limit

Specifically when there are many emails in the queue, prefetching
all their attachments at once when processing the first one
could fail, so not even one mail would be sent.

Added explicit logging when an email triggers a MemoryError,
as well as logging when each email is successfully sent.

bzr revid: odo@openerp.com-20140502144431-r3brgagl4gel4wmt
This commit is contained in:
Olivier Dony 2014-05-02 16:44:31 +02:00
parent deb091ea64
commit 61d2122987
1 changed files with 12 additions and 4 deletions

View File

@ -240,13 +240,17 @@ class mail_mail(osv.Model):
:return: True
"""
ir_mail_server = self.pool.get('ir.mail_server')
ir_attachment = self.pool['ir.attachment']
for mail in self.browse(cr, SUPERUSER_ID, ids, context=context):
try:
# handle attachments
attachments = []
for attach in mail.attachment_ids:
attachments.append((attach.datas_fname, base64.b64decode(attach.datas)))
# load attachment binary data with a separate read(), as prefetching all
# `datas` (binary field) could bloat the browse cache, triggerring
# soft/hard mem limits with temporary data.
attachment_ids = [a.id for a in mail.attachment_ids]
attachments = ((a['datas_fname'], base64.b64decode(a['datas']))
for a in ir_attachment.read(cr, uid, attachment_ids,
['datas_fname', 'datas']))
# specific behavior to customize the send email for notified partners
email_list = []
if mail.email_to:
@ -295,10 +299,14 @@ class mail_mail(osv.Model):
# /!\ can't use mail.state here, as mail.refresh() will cause an error
# see revid:odo@openerp.com-20120622152536-42b2s28lvdv3odyr in 6.1
if mail_sent:
_logger.info('Mail with ID %r and Message-Id %r successfully sent', mail.id, mail.message_id)
self._postprocess_sent_message(cr, uid, mail, context=context)
except MemoryError:
# prevent catching transient MemoryErrors, bubble up to notify user or abort cron job
# instead of marking the mail as failed
_logger.exception('MemoryError while processing mail with ID %r and Msg-Id %r. '\
'Consider raising the --limit-memory-hard startup option',
mail.id, mail.message_id)
raise
except Exception as e:
_logger.exception('failed sending mail.mail %s', mail.id)