我有一个使用imap IDLE协议检查gmail帐户的脚本。要做到这一点,我使用imaplib2,托管here。它经常抛出一个未处理的例外:
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\imaplib2\imaplib2.py", line 1830, in _reader
raise IOError("Too many read 0")
IOError: Too many read 0
(发布链接中的第1839行)
这是违规部分(中途):
def _reader(self):
threading.currentThread().setName(self.identifier + 'reader')
if __debug__: self._log(1, 'starting using select')
line_part = ''
rxzero = 0
terminate = False
while not (terminate or self.Terminate):
if self.state == LOGOUT:
timeout = 1
else:
timeout = self.read_poll_timeout
try:
r,w,e = select.select([self.read_fd], [], [], timeout)
if __debug__: self._log(5, 'select => %s, %s, %s' % (r,w,e))
if not r: # Timeout
continue
data = self.read(self.read_size) # Drain ssl buffer if present
start = 0
dlen = len(data)
if __debug__: self._log(5, 'rcvd %s' % dlen)
if dlen == 0:
rxzero += 1
if rxzero > 5:
raise IOError("Too many read 0") # <- This is the error I'm
time.sleep(0.1) # getting
else:
rxzero = 0
while True:
stop = data.find('\n', start)
if stop < 0:
line_part += data[start:]
break
stop += 1
line_part, start, line = \
'', stop, line_part + data[start:stop]
if __debug__: self._log(4, '< %s' % line)
self.inq.put(line)
if self.TerminateReader:
terminate = True
except:
reason = 'socket error: %s - %s' % sys.exc_info()[:2]
if __debug__:
if not self.Terminate:
self._print_log()
if self.debug: self.debug += 4 # Output all
self._log(1, reason)
self.inq.put((self.abort, reason))
break
我无法从我的脚本中捕获此错误,因为imaplib2为其_reader和_writer函数创建了单独的线程。我真的不明白错误,所以我的问题是我应该修改imaplib2源代码来忽略这个错误或改变它的条件或者什么?
由于
答案 0 :(得分:0)
我从imaplib2得到了各种各样的错误,包括errno 10054连接强制关闭和太多读取0.这些错误会导致我的程序挂起大约半小时。为了解决这些问题,我使用多处理在一个单独的过程中完成工作并实现了一个活动检查。如果一段时间内没有活动,主进程终止(我知道,不理想)子进程并生成另一个进程。以下是一些相关的代码。
def MasterRun():
from multiprocessing import Value
counter = Value("I", 0)
last = counter.value
elapsed = 0
interval = 1
TIMEOUT = 90
proc = _make_process(counter)
# value < 0 signals process quit naturally
while counter.value >= 0:
if counter.value != last:
elapsed = 0
last = counter.value
if elapsed >= TIMEOUT or not proc.is_alive():
print "terminating process reason: %s\n" % \
("no activity time was exceeded" if proc.is_alive() else "process committed suicide")
proc.terminate()
proc.join(25)
proc = _make_process(counter)
proc.start()
elapsed = 0
sleep(interval)
elapsed += interval
proc.join(25)
def _make_process(counter):
from multiprocessing import Process
print "spawning child process"
proc = Process(target=_make_instance, args=(counter, ))
proc.daemon = True
proc.start()
return proc