From 59a8234fbc89d6363a11b5ce3fc9929598dea930 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Thu, 21 Sep 2017 14:00:51 +0200 Subject: [PATCH] [FIX] mail performance: avoid useless queries Avoid making queries that are known to return empty recordsets, and do not format messages to be notified on no channel. --- addons/mail/models/mail_channel.py | 2 + addons/mail/models/mail_message.py | 37 +++++++++---------- .../tests/test_performance.py | 4 +- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py index bcf42cbb934..25b01ce80b5 100644 --- a/addons/mail/models/mail_channel.py +++ b/addons/mail/models/mail_channel.py @@ -302,6 +302,8 @@ class Channel(models.Model): of the received message indicates on wich mail channel the message should be displayed. :param : mail.message to broadcast """ + if not self: + return message.ensure_one() notifications = self._channel_message_notifications(message) self.env['bus.bus'].sendmany(notifications) diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index 439a09fdf8a..3adb170b0dc 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -794,13 +794,13 @@ class Message(models.Model): self_sudo = self.sudo() self.ensure_one() - partners_sudo = self.env['res.partner'].sudo() | self_sudo.partner_ids - channels_sudo = self.env['mail.channel'].sudo() | self_sudo.channel_ids + partners_sudo = self_sudo.partner_ids + channels_sudo = self_sudo.channel_ids # all followers of the mail.message document have to be added as partners and notified # and filter to employees only if the subtype is internal if self_sudo.subtype_id and self.model and self.res_id: - followers = self.env['mail.followers'].sudo().search([ + followers = self_sudo.env['mail.followers'].search([ ('res_model', '=', self.model), ('res_id', '=', self.res_id), ('subtype_ids', 'in', self_sudo.subtype_id.id), @@ -815,29 +815,28 @@ class Message(models.Model): partners_sudo = partners_sudo - self_sudo.author_id # update message, with maybe custom values - message_values = { - 'channel_ids': [(6, 0, channels_sudo.ids)], - 'needaction_partner_ids': [(6, 0, partners_sudo.ids)] - } + message_values = {} + if channels_sudo: + message_values['channel_ids'] = [(6, 0, channels_sudo.ids)] + if partners_sudo: + message_values['needaction_partner_ids'] = [(6, 0, partners_sudo.ids)] if self.model and self.res_id and hasattr(self.env[self.model], 'message_get_message_notify_values'): message_values.update(self.env[self.model].browse(self.res_id).message_get_message_notify_values(self, message_values)) - self.write(message_values) + if message_values: + self.write(message_values) # notify partners and channels # those methods are called as SUPERUSER because portal users posting messages # have no access to partner model. Maybe propagating a real uid could be necessary. email_channels = channels_sudo.filtered(lambda channel: channel.email_send) - # make a dedicated search on res.users to avoid user_ids.notification_type that will be user_ids.id in [ARRAY] - notif_users = self.env['res.users'].sudo().search([ - ('partner_id', 'in', partners_sudo.ids), - ('notification_type', '=', 'inbox') - ]) - partners_sudo.search([ - '|', - ('id', 'in', (partners_sudo - notif_users.mapped('partner_id')).ids), - ('channel_ids', 'in', email_channels.ids), - ('email', '!=', self_sudo.author_id and self_sudo.author_id.email or self_sudo.email_from), - ])._notify(self, force_send=force_send, send_after_commit=send_after_commit, user_signature=user_signature) + notif_partners = partners_sudo.filtered(lambda partner: 'inbox' in partner.mapped('user_ids.notification_type')) + if email_channels or partners_sudo - notif_partners: + partners_sudo.search([ + '|', + ('id', 'in', (partners_sudo - notif_partners).ids), + ('channel_ids', 'in', email_channels.ids), + ('email', '!=', self_sudo.author_id.email or self_sudo.email_from), + ])._notify(self, force_send=force_send, send_after_commit=send_after_commit, user_signature=user_signature) channels_sudo._notify(self) # Discard cache, because child / parent allow reading and therefore diff --git a/odoo/addons/test_performance/tests/test_performance.py b/odoo/addons/test_performance/tests/test_performance.py index 7dd81f18d96..53e7353e677 100644 --- a/odoo/addons/test_performance/tests/test_performance.py +++ b/odoo/addons/test_performance/tests/test_performance.py @@ -141,7 +141,7 @@ class TestPerformance(TransactionCase): records.write({'value': self.int(20)}) - @queryCount(admin=42, demo=59) + @queryCount(admin=22, demo=35) def test_write_mail_with_tracking(self): """ Write records inheriting from 'mail.thread' (with field tracking). """ record = self.env['test_performance.mail'].search([], limit=1) @@ -180,7 +180,7 @@ class TestPerformance(TransactionCase): model = self.env['test_performance.mail'] model.with_context(tracking_disable=True).create({'name': self.str('X')}) - @queryCount(admin=81, demo=107) + @queryCount(admin=43, demo=61) def test_create_mail_with_tracking(self): """ Create records inheriting from 'mail.thread' (with field tracking). """ model = self.env['test_performance.mail']