{"action":"created","issue":{"url":"https://api.github.com/repos/nylas/sync-engine/issues/157","labels_url":"https://api.github.com/repos/nylas/sync-engine/issues/157/labels{/name}","comments_url":"https://api.github.com/repos/nylas/sync-engine/issues/157/comments","events_url":"https://api.github.com/repos/nylas/sync-engine/issues/157/events","html_url":"https://github.com/nylas/sync-engine/issues/157","id":87241752,"number":157,"title":"IMAP commands should have a timeout","user":{"login":"thomasst","id":68381,"avatar_url":"https://avatars.githubusercontent.com/u/68381?v=3","gravatar_id":"","url":"https://api.github.com/users/thomasst","html_url":"https://github.com/thomasst","followers_url":"https://api.github.com/users/thomasst/followers","following_url":"https://api.github.com/users/thomasst/following{/other_user}","gists_url":"https://api.github.com/users/thomasst/gists{/gist_id}","starred_url":"https://api.github.com/users/thomasst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thomasst/subscriptions","organizations_url":"https://api.github.com/users/thomasst/orgs","repos_url":"https://api.github.com/users/thomasst/repos","events_url":"https://api.github.com/users/thomasst/events{/privacy}","received_events_url":"https://api.github.com/users/thomasst/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-06-11T07:21:02Z","updated_at":"2015-08-04T22:50:53Z","closed_at":null,"body":"Sometimes folders stop syncing (no heartbeat) and the greenlets aren't logging anything anymore. I inspected the frames of the stuck greenlets, and it seems like they are stuck in IMAP commands. Below is an example (these are from an IMAP account on imap.secureserver.net:993). Any IMAP commands should therefore have a timeout value and the connections should be re-established after a timeout.\r\n\r\n```\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/greenlet.py\", line 327, in run\r\n    result = self._run(*self.args, **self.kwargs)\r\n  File \"/home/ubuntu/inbox/inbox/mailsync/backends/imap/generic.py\", line 182, in _run\r\n    fail_classes=self.retry_fail_classes)\r\n  File \"/home/ubuntu/inbox/inbox/util/concurrency.py\", line 120, in retry_and_report_killed\r\n    **reset_params)()\r\n  File \"/home/ubuntu/inbox/inbox/util/concurrency.py\", line 73, in wrapped\r\n    return func(*args, **kwargs)\r\n  File \"/home/ubuntu/inbox/inbox/mailsync/backends/imap/generic.py\", line 205, in _run_impl\r\n    self.state = self.state_handlers[old_state]()\r\n  File \"/home/ubuntu/inbox/inbox/util/concurrency.py\", line 73, in wrapped\r\n    return func(*args, **kwargs)\r\n  File \"/home/ubuntu/inbox/inbox/mailsync/backends/imap/generic.py\", line 273, in poll\r\n    self.poll_impl()\r\n  File \"/home/ubuntu/inbox/inbox/mailsync/backends/imap/generic.py\", line 322, in poll_impl\r\n    crispin_client.select_folder(self.folder_name, uidvalidity_cb)\r\n  File \"/home/ubuntu/inbox/inbox/crispin.py\", line 332, in select_folder\r\n    folder, readonly=self.readonly)\r\n  File \"/home/ubuntu/inbox/src/imapclient/imapclient/imapclient.py\", line 403, in select_folder\r\n    self._command_and_check('select', self._normalise_folder(folder), readonly)\r\n  File \"/home/ubuntu/inbox/src/imapclient/imapclient/imapclient.py\", line 979, in _command_and_check\r\n    typ, data = meth(*args)\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 661, in select\r\n    typ, dat = self._simple_command(name, mailbox)\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 1087, in _simple_command\r\n    return self._command_complete(name, self._command(name, *args))\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 909, in _command_complete\r\n    typ, data = self._get_tagged_response(tag)\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 1016, in _get_tagged_response\r\n    self._get_response()\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 928, in _get_response\r\n    resp = self._get_line()\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 1026, in _get_line\r\n    line = self.readline()\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 1188, in readline\r\n    return self.file.readline()\r\n  File \"/usr/lib/python2.7/socket.py\", line 447, in readline\r\n    data = self._sock.recv(self._rbufsize)\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/ssl.py\", line 208, in recv\r\n    return self.read(buflen)\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/ssl.py\", line 119, in read\r\n    self._wait(self._read_event, timeout_exc=_SSLErrorReadTimeout)\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/socket.py\", line 298, in _wait\r\n    self.hub.wait(watcher)\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/hub.py\", line 341, in wait\r\n    result = waiter.get()\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/hub.py\", line 568, in get\r\n    return self.hub.switch()\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/hub.py\", line 331, in switch\r\n    return greenlet.switch(self)\r\n```\r\n\r\n```\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/greenlet.py\", line 327, in run\r\n    result = self._run(*self.args, **self.kwargs)\r\n  File \"/home/ubuntu/inbox/inbox/mailsync/backends/imap/generic.py\", line 182, in _run\r\n    fail_classes=self.retry_fail_classes)\r\n  File \"/home/ubuntu/inbox/inbox/util/concurrency.py\", line 120, in retry_and_report_killed\r\n    **reset_params)()\r\n  File \"/home/ubuntu/inbox/inbox/util/concurrency.py\", line 73, in wrapped\r\n    return func(*args, **kwargs)\r\n  File \"/home/ubuntu/inbox/inbox/mailsync/backends/imap/generic.py\", line 205, in _run_impl\r\n    self.state = self.state_handlers[old_state]()\r\n  File \"/home/ubuntu/inbox/inbox/util/concurrency.py\", line 73, in wrapped\r\n    return func(*args, **kwargs)\r\n  File \"/home/ubuntu/inbox/inbox/mailsync/backends/imap/generic.py\", line 273, in poll\r\n    self.poll_impl()\r\n  File \"/home/ubuntu/inbox/inbox/mailsync/backends/imap/generic.py\", line 325, in poll_impl\r\n    async_download=False)\r\n  File \"/home/ubuntu/inbox/inbox/mailsync/backends/imap/generic.py\", line 541, in check_uid_changes\r\n    remote_uids = set(crispin_client.all_uids())\r\n  File \"/home/ubuntu/inbox/inbox/crispin.py\", line 461, in all_uids\r\n    fetch_result = self.conn.search(['ALL'])\r\n  File \"/home/ubuntu/inbox/src/imapclient/imapclient/imapclient.py\", line 618, in search\r\n    return self._search(normalise_search_criteria(criteria), charset)\r\n  File \"/home/ubuntu/inbox/src/imapclient/imapclient/imapclient.py\", line 644, in _search\r\n    typ, data = self._imap.uid('SEARCH', *args)\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 772, in uid\r\n    typ, dat = self._simple_command(name, command, *args)\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 1087, in _simple_command\r\n    return self._command_complete(name, self._command(name, *args))\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 909, in _command_complete\r\n    typ, data = self._get_tagged_response(tag)\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 1016, in _get_tagged_response\r\n    self._get_response()\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 928, in _get_response\r\n    resp = self._get_line()\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 1026, in _get_line\r\n    line = self.readline()\r\n  File \"/usr/lib/python2.7/imaplib.py\", line 1188, in readline\r\n    return self.file.readline()\r\n  File \"/usr/lib/python2.7/socket.py\", line 447, in readline\r\n    data = self._sock.recv(self._rbufsize)\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/ssl.py\", line 208, in recv\r\n    return self.read(buflen)\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/ssl.py\", line 119, in read\r\n    self._wait(self._read_event, timeout_exc=_SSLErrorReadTimeout)\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/socket.py\", line 298, in _wait\r\n    self.hub.wait(watcher)\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/hub.py\", line 341, in wait\r\n    result = waiter.get()\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/hub.py\", line 568, in get\r\n    return self.hub.switch()\r\n  File \"/usr/local/lib/python2.7/dist-packages/gevent/hub.py\", line 331, in switch\r\n    return greenlet.switch(self)\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/nylas/sync-engine/issues/comments/127785024","html_url":"https://github.com/nylas/sync-engine/issues/157#issuecomment-127785024","issue_url":"https://api.github.com/repos/nylas/sync-engine/issues/157","id":127785024,"user":{"login":"thomasst","id":68381,"avatar_url":"https://avatars.githubusercontent.com/u/68381?v=3","gravatar_id":"","url":"https://api.github.com/users/thomasst","html_url":"https://github.com/thomasst","followers_url":"https://api.github.com/users/thomasst/followers","following_url":"https://api.github.com/users/thomasst/following{/other_user}","gists_url":"https://api.github.com/users/thomasst/gists{/gist_id}","starred_url":"https://api.github.com/users/thomasst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thomasst/subscriptions","organizations_url":"https://api.github.com/users/thomasst/orgs","repos_url":"https://api.github.com/users/thomasst/repos","events_url":"https://api.github.com/users/thomasst/events{/privacy}","received_events_url":"https://api.github.com/users/thomasst/received_events","type":"User","site_admin":false},"created_at":"2015-08-04T22:50:53Z","updated_at":"2015-08-04T22:50:53Z","body":"Nylas is using a global socket timeout now though, so this is currently not very important, but still useful to have in imapclient."}}