[FIX] mail: batch _insert_followers in create of mail.thread

The `_insert_followers` wasn't batch in the `create` of `mail.thread`
for no reason, which call the create of a `mail.follower` one by one.
It is inefficient for the batch records creation (import or some
flows) of a model with `_inherit = [mail.thread, ...]`.

Then batch it, to miminize the cost of `_insert_followers`:
The creation of 100 `mail.follower` takes:
- 0.107 sec if you create one by one (before)
- 0.022 sec if you create in batch (now)

Also add two tests (on model with a chatter):
- One testing the behavior of follower and subtype in case of
multi-create
- One testing the number of queries done to create 5 records.
The old SQL request count was 23, now it is 19 (-1 by create
call).

task-2711448

closes odoo/odoo#80954

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Rémy Voet (ryv)
2021-12-21 08:06:57 +00:00
parent 84e6fa1c77
commit 034d369c10
3 changed files with 20 additions and 8 deletions
+7 -8
View File
@@ -263,14 +263,13 @@ class MailThread(models.AbstractModel):
threads = super(MailThread, self).create(vals_list)
# subscribe uid unless asked not to
if not self._context.get('mail_create_nosubscribe'):
for thread in threads:
self.env['mail.followers']._insert_followers(
thread._name, thread.ids,
self.env.user.partner_id.ids, subtypes=None,
customer_ids=[],
check_existing=False
)
if not self._context.get('mail_create_nosubscribe') and threads:
self.env['mail.followers']._insert_followers(
threads._name, threads.ids,
self.env.user.partner_id.ids, subtypes=None,
customer_ids=[],
check_existing=False
)
# auto_subscribe: take values and defaults into account
create_values_list = {}
@@ -162,6 +162,13 @@ class BaseFollowersTest(TestMailCommon):
document._message_subscribe(partner_ids=(self.partner_portal | private_address).ids)
self.assertEqual(document.message_follower_ids.partner_id, self.partner_portal | private_address)
@users('employee')
def test_create_multi_followers(self):
documents = self.env['mail.test.simple'].create([{'name': 'ninja'}] * 5)
for document in documents:
self.assertEqual(document.message_follower_ids.partner_id, self.env.user.partner_id)
self.assertEqual(document.message_follower_ids.subtype_ids, self.default_group_subtypes)
@tagged('mail_followers')
class AdvancedFollowersTest(TestMailCommon):
@@ -193,6 +193,12 @@ class TestBaseMailPerformance(BaseMailPerformance):
with self.assertQueryCount(__system__=7, employee=7):
self.env['mail.test.simple'].create({'name': 'Test'})
@users('__system__', 'employee')
@warmup
def test_create_mail_simple_multi(self):
with self.assertQueryCount(__system__=19, employee=19):
self.env['mail.test.simple'].create([{'name': 'Test'}] * 5)
@users('__system__', 'employee')
@warmup
def test_write_mail_simple(self):