summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorAurélien (avd) <avd@odoo.com>2021-03-03 16:46:00 +0000
committerAurélien (avd) <avd@odoo.com>2021-04-16 08:25:41 +0000
commita05244c0b2a1d9c873696f7a856c438435e4cdf5 (patch)
tree6bf6a64d205e5c1c24651db70432b3e875b3bcb8 /addons
parent3e20e68f0790a0b0f3b5c4d43f59f235b7d20fef (diff)
[FIX] google_calendar: turn off notifications to improve perfs.
Turn off calendar.attendees notification during synced_events creation to improve performances. The calendar notification are only computed once after all the synced events have been created. Add a flag in google_calendar.js to avoid retriggering synchronization while navigating the calendar view if the past synchronization is still pending.
Diffstat (limited to 'addons')
-rw-r--r--addons/google_calendar/models/calendar.py7
-rw-r--r--addons/google_calendar/models/calendar_recurrence_rule.py17
-rw-r--r--addons/google_calendar/models/google_sync.py19
-rw-r--r--addons/google_calendar/static/src/js/google_calendar.js9
4 files changed, 47 insertions, 5 deletions
diff --git a/addons/google_calendar/models/calendar.py b/addons/google_calendar/models/calendar.py
index ba455fa2111..0079c9c049d 100644
--- a/addons/google_calendar/models/calendar.py
+++ b/addons/google_calendar/models/calendar.py
@@ -226,3 +226,10 @@ class Meeting(models.Model):
super(Meeting, my_cancelled_records)._cancel()
attendees = (self - my_cancelled_records).attendee_ids.filtered(lambda a: a.partner_id == user.partner_id)
attendees.state = 'declined'
+
+ def _notify_attendees(self):
+ # filter events before notifying attendees through calendar_alarm_manager
+ need_notifs = self.filtered(lambda event: event.alarm_ids and event.stop >= fields.Datetime.now())
+ partners = need_notifs.partner_ids
+ if partners:
+ self.env['calendar.alarm_manager']._notify_next_alarm(partners.ids)
diff --git a/addons/google_calendar/models/calendar_recurrence_rule.py b/addons/google_calendar/models/calendar_recurrence_rule.py
index 055359fa8f9..c9ff1566e9f 100644
--- a/addons/google_calendar/models/calendar_recurrence_rule.py
+++ b/addons/google_calendar/models/calendar_recurrence_rule.py
@@ -2,6 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import re
+from dateutil.relativedelta import relativedelta
from odoo import api, fields, models
@@ -131,8 +132,10 @@ class RecurrenceRule(models.Model):
vals['calendar_event_ids'] = [(4, base_event.id)]
# event_tz is written on event in Google but on recurrence in Odoo
vals['event_tz'] = gevent.start.get('timeZone')
- recurrence = super()._create_from_google(gevents, vals_list)
- recurrence._apply_recurrence()
+ recurrence = super(RecurrenceRule, self.with_context(dont_notify=True))._create_from_google(gevents, vals_list)
+ recurrence.with_context(dont_notify=True)._apply_recurrence()
+ if not recurrence._context.get("dont_notify"):
+ recurrence._notify_attendees()
return recurrence
def _get_sync_domain(self):
@@ -172,3 +175,13 @@ class RecurrenceRule(models.Model):
},
}
return values
+
+ def _notify_attendees(self):
+ recurrences = self.filtered(
+ lambda recurrence: recurrence.base_event_id.alarm_ids and (
+ not recurrence.until or recurrence.until >= fields.Date.today() - relativedelta(days=1)
+ ) and (max(recurrence.calendar_event_ids.mapped('stop')) >= fields.Datetime.now())
+ )
+ partners = recurrences.base_event_id.partner_ids
+ if partners:
+ self.env['calendar.alarm_manager']._notify_next_alarm(partners.ids)
diff --git a/addons/google_calendar/models/google_sync.py b/addons/google_calendar/models/google_sync.py
index e1486bac47e..94be4051735 100644
--- a/addons/google_calendar/models/google_sync.py
+++ b/addons/google_calendar/models/google_sync.py
@@ -155,12 +155,15 @@ class GoogleSync(models.AbstractModel):
dict(self._odoo_values(e, default_reminders), need_sync=False)
for e in new
]
- new_odoo = self._create_from_google(new, odoo_values)
+ new_odoo = self.with_context(dont_notify=True)._create_from_google(new, odoo_values)
+ # Synced recurrences attendees will be notified once _apply_recurrence is called.
+ if not self._context.get("dont_notify") and all(not e.is_recurrence() for e in google_events):
+ new_odoo._notify_attendees()
+
cancelled = existing.cancelled()
cancelled_odoo = self.browse(cancelled.odoo_ids(self.env))
cancelled_odoo._cancel()
-
- synced_records = new_odoo + cancelled_odoo
+ synced_records = (new_odoo + cancelled_odoo).with_context(dont_notify=self._context.get("dont_notify", False))
for gevent in existing - cancelled:
# Last updated wins.
# This could be dangerous if google server time and odoo server time are different
@@ -251,3 +254,13 @@ class GoogleSync(models.AbstractModel):
marks the record to be re-synchronized.
"""
raise NotImplementedError()
+
+ def _notify_attendees(self):
+ """ Notify calendar event partners.
+ This is called when creating new calendar events in _sync_google2odoo.
+ At the initialization of a synced calendar, Odoo requests all events for a specific
+ GoogleCalendar. Among those there will probably be lots of events that will never triggers a notification
+ (e.g. single events that occured in the past). Processing all these events through the notification procedure
+ of calendar.event.create is a possible performance bottleneck. This method aimed at alleviating that.
+ """
+ raise NotImplementedError()
diff --git a/addons/google_calendar/static/src/js/google_calendar.js b/addons/google_calendar/static/src/js/google_calendar.js
index ec8313e0e9e..6e250d7b8da 100644
--- a/addons/google_calendar/static/src/js/google_calendar.js
+++ b/addons/google_calendar/static/src/js/google_calendar.js
@@ -21,6 +21,7 @@ const GoogleCalendarModel = CalendarModel.include({
init: function () {
this._super.apply(this, arguments);
this.google_is_sync = true;
+ this.google_pending_sync = false;
},
/**
@@ -39,6 +40,11 @@ const GoogleCalendarModel = CalendarModel.include({
*/
async _loadCalendar() {
const _super = this._super.bind(this);
+ // When the calendar synchronization takes some time, prevents retriggering the sync while navigating the calendar.
+ if (this.google_pending_sync) {
+ return _super(...arguments);
+ }
+
try {
await Promise.race([
new Promise(resolve => setTimeout(resolve, 1000)),
@@ -49,6 +55,7 @@ const GoogleCalendarModel = CalendarModel.include({
error.event.preventDefault();
}
console.error("Could not synchronize Google events now.", error);
+ this.google_pending_sync = false;
}
return _super(...arguments);
},
@@ -56,6 +63,7 @@ const GoogleCalendarModel = CalendarModel.include({
_syncGoogleCalendar(shadow = false) {
var self = this;
var context = this.getSession().user_context;
+ this.google_pending_sync = true;
return this._rpc({
route: '/google_calendar/sync_data',
params: {
@@ -69,6 +77,7 @@ const GoogleCalendarModel = CalendarModel.include({
} else if (result.status === "no_new_event_from_google" || result.status === "need_refresh") {
self.google_is_sync = true;
}
+ self.google_pending_sync = false;
return result
});
},