diff options
| author | Odoo's Mergebot <xmo+roboto@odoo.com> | 2019-09-13 10:44:22 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-09-13 10:44:22 +0200 |
| commit | 4926f03e6fb87eef4d64cc8779abafb7f3713cfa (patch) | |
| tree | 34e1eb72e7522cc336af310e1417dc3f9016ca07 | |
| parent | 5dc97ee7daa1772f1b895976b0eb17425de11c52 (diff) | |
| parent | c8f2924c66f32e8cc601fefda938875d5444f88f (diff) | |
[MERGE] mail: improve record creation with batch operations
PURPOSE
Optimize record creation in mail module by adding batch operations.
SPECIFICATIONS
Compute default followers once at creation for all created records. As the
same value is computed for each new record computing it once is sufficient.
Log default creation message in batch when having no specific subtype at
create. It allows to speedup record creation. For 1000 records, these specific
lines take
* 2.1s before the commit
* 1.2s after the commit
LINKS
PR #36654
Task 2070602
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
| -rw-r--r-- | addons/mail/models/mail_thread.py | 18 | ||||
| -rw-r--r-- | addons/test_mail/tests/test_performance.py | 70 |
2 files changed, 46 insertions, 42 deletions
diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index e0bc166a1a9..94ae2e4b448 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -260,9 +260,10 @@ class MailThread(models.AbstractModel): # subscribe uid unless asked not to if not self._context.get('mail_create_nosubscribe'): + default_followers = self.env['mail.followers']._add_default_followers(self._name, [], self.env.user.partner_id.ids, customer_ids=[])[0][0] for values in vals_list: message_follower_ids = values.get('message_follower_ids') or [] - message_follower_ids += [(0, 0, fol_vals) for fol_vals in self.env['mail.followers']._add_default_followers(self._name, [], self.env.user.partner_id.ids, customer_ids=[])[0][0]] + message_follower_ids += [(0, 0, fol_vals) for fol_vals in default_followers] values['message_follower_ids'] = message_follower_ids threads = super(MailThread, self).create(vals_list) @@ -280,13 +281,16 @@ class MailThread(models.AbstractModel): # automatic logging unless asked not to (mainly for various testing purpose) if not self._context.get('mail_create_nolog'): doc_name = self.env['ir.model']._get(self._name).name + body = _('%s created') % doc_name + threads_no_subtype = self.env[self._name] for thread in threads: subtype = thread._creation_subtype() - body = _('%s created') % doc_name - if subtype: # if we have a sybtype, post message to notify users from _message_auto_subscribe + if subtype: # if we have a subtype, post message to notify users from _message_auto_subscribe thread.sudo().message_post(body=body, subtype_id=subtype.id, author_id=self.env.user.partner_id.id) else: - thread._message_log(body=body) + threads_no_subtype += thread + if threads_no_subtype: + threads_no_subtype._message_log_batch(bodies={t.id: body for t in threads_no_subtype}) # post track template if a tracked field changed if not self._context.get('mail_notrack'): @@ -554,8 +558,9 @@ class MailThread(models.AbstractModel): def _creation_subtype(self): """ Give the subtypes triggered by the creation of a record - :returns: a subtype browse record or False if no subtype is trigerred + :returns: a subtype browse record (empty if no subtype is triggered) """ + return self.env['mail.message.subtype'] def _track_subtype(self, init_values): """ Give the subtypes triggered by the changes on the record according @@ -1019,8 +1024,7 @@ class MailThread(models.AbstractModel): message_dict.pop('parent_id', None) thread = ModelCtx.message_new(message_dict, custom_values) thread_id = thread.id - subtype = thread._creation_subtype() - subtype_id = subtype.id if subtype else False + subtype_id = thread._creation_subtype().id # replies to internal message are considered as notes, but parent message # author is added in recipients to ensure he is notified of a private answer diff --git a/addons/test_mail/tests/test_performance.py b/addons/test_mail/tests/test_performance.py index 9064cedb812..919d6ac9dd7 100644 --- a/addons/test_mail/tests/test_performance.py +++ b/addons/test_mail/tests/test_performance.py @@ -65,7 +65,7 @@ class TestMailPerformance(BaseMailPerformance): records = self.env['test_performance.mail'].search([]) self.assertEqual(len(records), 5) - with self.assertQueryCount(__system__=3, demo=3): # test_mail only: 3 - 3 + with self.assertQueryCount(__system__=3, demo=3): records.write({'name': 'X'}) @users('__system__', 'demo') @@ -75,7 +75,7 @@ class TestMailPerformance(BaseMailPerformance): records = self.env['test_performance.mail'].search([]) self.assertEqual(len(records), 5) - with self.assertQueryCount(__system__=5, demo=5): # test_mail only: 5 - 5 + with self.assertQueryCount(__system__=3, demo=3): records.write({'value': 42}) @users('__system__', 'demo') @@ -89,7 +89,7 @@ class TestMailPerformance(BaseMailPerformance): 'partner_id': self.env.ref('base.res_partner_12').id, }) - with self.assertQueryCount(__system__=4, demo=4): # test_mail only: 4 - 4 + with self.assertQueryCount(__system__=3, demo=3): record.track = 'X' @users('__system__', 'demo') @@ -98,27 +98,27 @@ class TestMailPerformance(BaseMailPerformance): """ Create records inheriting from 'mail.thread' (without field tracking). """ model = self.env['test_performance.mail'] - with self.assertQueryCount(__system__=3, demo=3): # test_mail only: 3 - 3 + with self.assertQueryCount(__system__=2, demo=2): model.with_context(tracking_disable=True).create({'name': 'X'}) @users('__system__', 'demo') @warmup def test_create_mail_with_tracking(self): """ Create records inheriting from 'mail.thread' (with field tracking). """ - with self.assertQueryCount(__system__=8, demo=8): # test_mail only: 8 - 8 + with self.assertQueryCount(__system__=7, demo=7): self.env['test_performance.mail'].create({'name': 'X'}) @users('__system__', 'emp') @warmup def test_create_mail_simple(self): - with self.assertQueryCount(__system__=6, emp=6): # test_mail only: 6 - 6 + with self.assertQueryCount(__system__=6, emp=6): self.env['mail.test.simple'].create({'name': 'Test'}) @users('__system__', 'emp') @warmup def test_write_mail_simple(self): rec = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=1, emp=1): # test_mail only: 1 - 1 + with self.assertQueryCount(__system__=1, emp=1): rec.write({ 'name': 'Test2', 'email_from': 'test@test.com', @@ -150,7 +150,7 @@ class TestAdvMailPerformance(BaseMailPerformance): def test_adv_activity(self): model = self.env['mail.test.activity'] - with self.assertQueryCount(__system__=7, emp=6): # test_mail only: 7 - 6 + with self.assertQueryCount(__system__=6, emp=6): model.create({'name': 'Test'}) @users('__system__', 'emp') @@ -162,7 +162,7 @@ class TestAdvMailPerformance(BaseMailPerformance): 'default_res_model': 'mail.test.activity', }) - with self.assertQueryCount(__system__=10, emp=13): # com runbot: 10 - 13 // test_mail only: 10 - 13 + with self.assertQueryCount(__system__=6, emp=6): activity = MailActivity.create({ 'summary': 'Test Activity', 'res_id': record.id, @@ -172,7 +172,7 @@ class TestAdvMailPerformance(BaseMailPerformance): #voip module read activity_type during create leading to one less query in enterprise on action_feedback category = activity.activity_type_id.category - with self.assertQueryCount(__system__=24, emp=31): # com runbot: 24 - 31 // test_mail only: 24 - 31 + with self.assertQueryCount(__system__=19, emp=22): activity.action_feedback(feedback='Zizisse Done !') @users('__system__', 'emp') @@ -181,7 +181,7 @@ class TestAdvMailPerformance(BaseMailPerformance): def test_adv_activity_mixin(self): record = self.env['mail.test.activity'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=10, emp=14): # com runbot: 10 - 14 // test_mail only: 10 - 14 + with self.assertQueryCount(__system__=7, emp=7): activity = record.action_start('Test Start') #read activity_type to normalize cache between enterprise and community #voip module read activity_type during create leading to one less query in enterprise on action_close @@ -189,7 +189,7 @@ class TestAdvMailPerformance(BaseMailPerformance): record.write({'name': 'Dupe write'}) - with self.assertQueryCount(__system__=26, emp=31): # com runbot: 26 - 31 // test_mail only: 26 - 31 + with self.assertQueryCount(__system__=20, emp=22): record.action_close('Dupe feedback') self.assertEqual(record.activity_ids, self.env['mail.activity']) @@ -200,7 +200,7 @@ class TestAdvMailPerformance(BaseMailPerformance): def test_message_assignation_email(self): self.user_test.write({'notification_type': 'email'}) record = self.env['mail.test.track'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=52, emp=54): # com runbot: 52 - 54 // test_mail only: 52 - 54 + with self.assertQueryCount(__system__=39, emp=40): record.write({ 'user_id': self.user_test.id, }) @@ -209,7 +209,7 @@ class TestAdvMailPerformance(BaseMailPerformance): @warmup def test_message_assignation_inbox(self): record = self.env['mail.test.track'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=32, emp=37): # test_mail only: 32 - 37 + with self.assertQueryCount(__system__=27, emp=29): record.write({ 'user_id': self.user_test.id, }) @@ -219,7 +219,7 @@ class TestAdvMailPerformance(BaseMailPerformance): def test_message_log(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=1, emp=1): # test_mail only: 1 - 1 + with self.assertQueryCount(__system__=1, emp=1): record._message_log( body='<p>Test _message_log</p>', message_type='comment') @@ -229,7 +229,7 @@ class TestAdvMailPerformance(BaseMailPerformance): def test_message_log_with_post(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=6, emp=7): # test_mail only: 6 - 7 + with self.assertQueryCount(__system__=5, emp=6): record.message_post( body='<p>Test message_post as log</p>', subtype='mail.mt_note', @@ -240,7 +240,7 @@ class TestAdvMailPerformance(BaseMailPerformance): def test_message_post_no_notification(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=6, emp=7): # test_mail only: 6 - 7 + with self.assertQueryCount(__system__=5, emp=6): record.message_post( body='<p>Test Post Performances basic</p>', partner_ids=[], @@ -253,7 +253,7 @@ class TestAdvMailPerformance(BaseMailPerformance): def test_message_post_one_email_notification(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=44, emp=47): # com runbot: 44 - 47 // test_mail only: 44 - 47 + with self.assertQueryCount(__system__=32, emp=33): record.message_post( body='<p>Test Post Performances with an email ping</p>', partner_ids=self.customer.ids, @@ -265,7 +265,7 @@ class TestAdvMailPerformance(BaseMailPerformance): def test_message_post_one_inbox_notification(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=29, emp=34): # com runbot 29 - 34 // test_mail only: 29 - 34 + with self.assertQueryCount(__system__=23, emp=25): record.message_post( body='<p>Test Post Performances with an inbox ping</p>', partner_ids=self.user_test.partner_id.ids, @@ -278,10 +278,10 @@ class TestAdvMailPerformance(BaseMailPerformance): def test_message_subscribe_default(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=6, emp=6): # test_mail only: 6 - 6 + with self.assertQueryCount(__system__=6, emp=6): record.message_subscribe(partner_ids=self.user_test.partner_id.ids) - with self.assertQueryCount(__system__=3, emp=3): # test_mail only: 3 - 3 + with self.assertQueryCount(__system__=3, emp=3): record.message_subscribe(partner_ids=self.user_test.partner_id.ids) @mute_logger('odoo.models.unlink') @@ -291,10 +291,10 @@ class TestAdvMailPerformance(BaseMailPerformance): record = self.env['mail.test.simple'].create({'name': 'Test'}) subtype_ids = (self.env.ref('test_mail.st_mail_test_simple_external') | self.env.ref('mail.mt_comment')).ids - with self.assertQueryCount(__system__=5, emp=5): # test_mail only: 5 - 5 + with self.assertQueryCount(__system__=5, emp=5): record.message_subscribe(partner_ids=self.user_test.partner_id.ids, subtype_ids=subtype_ids) - with self.assertQueryCount(__system__=2, emp=2): # test_mail only: 2 - 2 + with self.assertQueryCount(__system__=2, emp=2): record.message_subscribe(partner_ids=self.user_test.partner_id.ids, subtype_ids=subtype_ids) @@ -362,7 +362,7 @@ class TestHeavyMailPerformance(BaseMailPerformance): 'recipient_ids': [(4, pid) for pid in self.partners.ids], }) mail_ids = mail.ids - with self.assertQueryCount(__system__=16, emp=21): # test_mail only: 16 - 21 + with self.assertQueryCount(__system__=7, emp=7): self.env['mail.mail'].browse(mail_ids).send() self.assertEqual(mail.body_html, '<p>Test</p>') @@ -375,7 +375,7 @@ class TestHeavyMailPerformance(BaseMailPerformance): self.umbrella.message_subscribe(self.user_portal.partner_id.ids) record = self.umbrella.with_user(self.env.user) - with self.assertQueryCount(__system__=82, emp=85): # com runbot: 82 - 85 // test_mail only: 82 - 85 + with self.assertQueryCount(__system__=71, emp=72): record.message_post( body='<p>Test Post Performances</p>', message_type='comment', @@ -392,7 +392,7 @@ class TestHeavyMailPerformance(BaseMailPerformance): record = self.umbrella.with_user(self.env.user) template_id = self.env.ref('test_mail.mail_test_tpl').id - with self.assertQueryCount(__system__=98, emp=103): # com runbot: 98 - 103 // test_mail only: 98 - 103 + with self.assertQueryCount(__system__=81, emp=82): record.message_post_with_template(template_id, message_type='comment', composition_mode='comment') self.assertEqual(record.message_ids[0].body, '<p>Adding stuff on %s</p>' % record.name) @@ -417,7 +417,7 @@ class TestHeavyMailPerformance(BaseMailPerformance): self.assertEqual(rec.message_channel_ids, self.env['mail.channel']) # subscribe new followers with forced given subtypes - with self.assertQueryCount(__system__=8, emp=8): # test_mail only: 8 - 8 + with self.assertQueryCount(__system__=8, emp=8): rec.message_subscribe( partner_ids=pids[:4], channel_ids=cids, @@ -428,7 +428,7 @@ class TestHeavyMailPerformance(BaseMailPerformance): self.assertEqual(rec.message_channel_ids, self.channel) # subscribe existing and new followers with force=False, meaning only some new followers will be added - with self.assertQueryCount(__system__=6, emp=6): # test_mail only: 6 - 6 + with self.assertQueryCount(__system__=6, emp=6): rec.message_subscribe( partner_ids=pids[:6], channel_ids=cids, @@ -439,7 +439,7 @@ class TestHeavyMailPerformance(BaseMailPerformance): self.assertEqual(rec.message_channel_ids, self.channel) # subscribe existing and new followers with force=True, meaning all will have the same subtypes - with self.assertQueryCount(__system__=7, emp=7): # test_mail only: 7 - 7 + with self.assertQueryCount(__system__=7, emp=7): rec.message_subscribe( partner_ids=pids, channel_ids=cids, @@ -461,7 +461,7 @@ class TestHeavyMailPerformance(BaseMailPerformance): 'user_id': self.env.uid, }) self.assertEqual(rec.message_partner_ids, self.partners | self.env.user.partner_id) - with self.assertQueryCount(__system__=52, emp=53): # com runbot: 51 - 53 // test_mail only: 51 - 53 + with self.assertQueryCount(__system__=39, emp=40): rec.write({'user_id': self.user_portal.id}) self.assertEqual(rec.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id) # write tracking message @@ -481,7 +481,7 @@ class TestHeavyMailPerformance(BaseMailPerformance): customer_id = self.customer.id user_id = self.user_portal.id - with self.assertQueryCount(__system__=146, emp=149): # com runbot: 146 - 149 // test_mail only: 146 - 149 + with self.assertQueryCount(__system__=121, emp=122): rec = self.env['mail.test.full'].create({ 'name': 'Test', 'umbrella_id': umbrella_id, @@ -508,7 +508,7 @@ class TestHeavyMailPerformance(BaseMailPerformance): }) self.assertEqual(rec.message_partner_ids, self.user_portal.partner_id | self.env.user.partner_id) self.assertEqual(len(rec.message_ids), 1) - with self.assertQueryCount(__system__=100, emp=106): # com runbot: 100 -106 // test_mail only: 100 - 106 + with self.assertQueryCount(__system__=84, emp=85): rec.write({ 'name': 'Test2', 'umbrella_id': self.umbrella.id, @@ -544,7 +544,7 @@ class TestHeavyMailPerformance(BaseMailPerformance): }) self.assertEqual(rec.message_partner_ids, self.user_portal.partner_id | self.env.user.partner_id) - with self.assertQueryCount(__system__=105, emp=111): # test_mail only: 105 - 111 + with self.assertQueryCount(__system__=92, emp=93): rec.write({ 'name': 'Test2', 'umbrella_id': umbrella_id, @@ -576,7 +576,7 @@ class TestHeavyMailPerformance(BaseMailPerformance): }) self.assertEqual(rec.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id) - with self.assertQueryCount(__system__=50, emp=63): # test_mail only: 50 - 63 + with self.assertQueryCount(__system__=33, emp=35): rec.write({ 'name': 'Test2', 'customer_id': customer_id, @@ -713,7 +713,7 @@ class TestMailPerformancePost(BaseMailPerformance): ] self.attachements = self.env['ir.attachment'].with_user(self.env.user).create(self.vals) attachement_ids = self.attachements.ids - with self.assertQueryCount(emp=175): # com runbot 154 // test_mail only: 132 + with self.assertQueryCount(emp=118): # runbot 118 // test_mail only: 110 self.cr.sql_log = self.warm and self.cr.sql_log_count record.with_context({}).message_post( body='<p>Test body <img src="cid:cid1"> <img src="cid:cid2"></p>', |
