From 6c7dbe902d8679570ca10f39672d844fa5cb6c50 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Fri, 19 Jun 2020 12:05:46 -0300 Subject: GMail: Instead of polling each Label, poll the profile The global history_id covers all labels, if we see it change then do a delta query to all the labels to figure things out. This reduces the amount of server traffic if there are multiple labels. Signed-off-by: Jason Gunthorpe --- cloud_mdir_sync/gmail.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/cloud_mdir_sync/gmail.py b/cloud_mdir_sync/gmail.py index b621577..dc70361 100644 --- a/cloud_mdir_sync/gmail.py +++ b/cloud_mdir_sync/gmail.py @@ -77,6 +77,7 @@ class GmailAPI(oauth.Account): def __init__(self, cfg: config.Config, user: str): super().__init__(cfg, user) self.domain_id = f"gmail-{user}" + self.mailboxes = [] async def go(self): cfg = self.cfg @@ -100,6 +101,18 @@ class GmailAPI(oauth.Account): token=self.api_token) await self._do_authenticate() + asyncio.create_task(self._poll_for_changes()) + + async def _poll_for_changes(self): + while True: + await asyncio.sleep(60) + profile = await self.get_json("v1","/users/me/profile") + history_id = int(profile["historyId"]) + for mbox in self.mailboxes: + if (mbox.history_delta is not None + and int(mbox.history_delta[1]) < history_id): + mbox.need_update = True + mbox.changed_event.set() def _set_token(self, api_token): # Only store the refresh token, access tokens are more dangerous to @@ -314,7 +327,6 @@ class GMailMailbox(mailbox.Mailbox): supported_flags = (messages.Message.FLAG_READ | messages.Message.FLAG_FLAGGED | messages.Message.FLAG_DELETED) - timer = None gmail: GmailAPI gmail_messages: Dict[str, GMailMessage] history_delta = None @@ -326,6 +338,7 @@ class GMailMailbox(mailbox.Mailbox): self.gmail = gmail self.gmail_messages = {} self.max_fetches = asyncio.Semaphore(10) + gmail.mailboxes.append(self) def __repr__(self): return f"" @@ -504,14 +517,6 @@ class GMailMailbox(mailbox.Mailbox): for msg in self.history_delta[0] if msg.content_hash is not None } self.need_update = False - if self.timer: - self.timer.cancel() - self.timer = None - self.timer = self.cfg.loop.call_later(60, self._timer) - - def _timer(self): - self.need_update = True - self.changed_event.set() def force_content(self, msgs): raise RuntimeError("Cannot move messages into the Cloud") -- cgit v1.2.3