Search code examples
python-2.7cherrypy

Restarting a Monitor instance


I have a cherrypy app that's got a Monitor instance like so:

        mail_checker = Monitor(cherrypy.engine, self.mail_processor.poll_history_feed, frequency=10)

To put it simply it checks a gmail inbox for new emails and processes them. Sometimes poll_history_feed() will throw an exception, I'm guessing right now that its because of our unstable internet, and it ceases to run until I restart the whole app. (sample of the traceback below)

    [01/Mar/2016:17:08:29] ENGINE Error in background task thread function <bound method MailProcessor.poll_history_feed of <mailservices.mailprocessor.MailProcessor object at 0x10a2f0250>>.
Traceback (most recent call last):
  File "/Users/hashtaginteractive/Projects/.venvs/emaild/lib/python2.7/site-packages/cherrypy/process/plugins.py", line 500, in run
    self.function(*self.args, **self.kwargs)
  File "/Users/hashtaginteractive/Projects/emaild/emaild-source/mailservices/mailprocessor.py", line 12, in poll_history_feed
    labelIds=["INBOX", "UNREAD"]
  File "/Users/hashtaginteractive/Projects/.venvs/emaild/lib/python2.7/site-packages/oauth2client/util.py", line 142, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/Users/hashtaginteractive/Projects/.venvs/emaild/lib/python2.7/site-packages/googleapiclient/http.py", line 730, in execute
    return self.postproc(resp, content)
  File "/Users/hashtaginteractive/Projects/.venvs/emaild/lib/python2.7/site-packages/googleapiclient/model.py", line 207, in response
    return self.deserialize(content)
  File "/Users/hashtaginteractive/Projects/.venvs/emaild/lib/python2.7/site-packages/googleapiclient/model.py", line 262, in deserialize
    content = content.decode('utf-8')
  File "/Users/hashtaginteractive/Projects/.venvs/emaild/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0x8b in position 23: invalid start byte

Is there any way to set this up so that it automatically restarts either the server or this particular Monitor instance whenever an exception happens?


Solution

  • You have to wrap the call to self.mail_processor.poll_history_feed in a try/except block and log the error for convenience.

    def safe_poll_history_feed(self):
        try:
            self.mail_processor.poll_history_feed()
        except Exception:
            cherrypy.engine.log("Exception in mailprocessor monitor", traceback=True)
    

    And then use the safe_poll_history_feed method