5

终止永远等待网络的程序——纠结的 getmail 不再纠结

 3 years ago
source link: https://blog.lilydjwg.me/2013/11/10/kill-proceses-that-would-hang-forever.41646.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

终止永远等待网络的程序——纠结的 getmail 不再纠结

本文来自依云's Blog,转载请注明。

我收取邮件一直用的是 getmail,然而它有个问题:在网络不好的时候会挂在 recv 系统调用上,等好几个小时都有可能。还好我用的 crond 是 dcron,它知道同一个任务,在上一次任务还没执行完时即使时间到了也不应该再次执行,省了我一堆 flock 锁。不过,这样子导致我收不到邮件也不行啊。

以前也研究过一次,看到 getmail 有设置 socket 的超时时间啊,没整明白。最近网络又老是抽风,而且相当严重,导致我得不断地用 htop 去看、去杀没有反应的 getmail 进程。烦了,于是一边阅读 getmail 源码,一边使用 strace 观察,再配合 iptables 这神器,以及 the Silver searcher,终于找到了问题所在。

原来,由于 Python 的 SSL 对非阻塞套接字的支持问题12,getmail 在使用 SSL 连接时会强制使用阻塞式的套接字(见代码getmailcore/_pop3ssl.py:39以及getmailcore/_retrieverbases.py:187)。也许 Python 2.7 已经解决了这个问题,但是看上去 getmail 还是比较关心 Python 2.3 和 2.4。不过就算是 SSL 支持不好,调用下alarm不要一直待在那里傻傻地等嘛……也许,大部分 getmail 用户很少遇到足够差的网络?

于是考虑 fetchmail。花了两三天的业余时间终于弄明白我的需求该怎么配置了:

set daemon 300
set logfile ~/etc/log/fetchmail.log
defaults proto pop3 timeout 120 uidl
keep fetchsizelimit 0 mda "procmail -f %T"
poll pop.163.com interval 2
username "username" password "password"
poll pop.gmail.com
username "username" password "password"
ssl
poll pop.qq.com interval 2016 # 7 days
username "username" password "password"

但结果就是,除了 GMail 好一点,我让它「对从现在起所收到的邮件启用 POP」就没太大问题之外,腾讯还好,没几封邮件。网易那边,几百封旧邮件全部拖回来了…………

其实这个问题也还好,毕竟是一次性的。可我看它的日志,又发现,它每次收到 GMail 时,都会打印有多少封邮件已读。难道说,它每次去收邮件时都要列出所有可以用 POP3 收取的邮件,然后挑出没有收取过的?想到如果是这样,以后它每次取邮件时都要先取几千上万条已读邮件列表……这不跟 Google App Engine SDK 操作数据库加 offset 时前边所有数据全部读一遍一样扯淡吗……

于是又回来折腾 getmail。其实就这么一个问题,解决了就好。本来是准备去学学ptrace怎么用的,结果忍不住了,直接拿 Python 调 strace 写了这个:

killhung
#!/usr/bin/env python3
'''wait and kill subprocess if it doesn't response (from network)'''
import os
import sys
import select
import tempfile
import subprocess
timeout = 60
def new_group():
os.setpgrp()
def main(args):
path = os.path.join('/dev/shm', '_'.join(args).replace('/', '-'))
if not os.path.exists(path):
os.mkfifo(path, 0o600)
pipe = os.open(path, os.O_RDONLY | os.O_NONBLOCK)
p = subprocess.Popen(['strace', '-o', path, '-e', 'trace=network'] + args, preexec_fn=new_group)
try:
while True:
ret = p.poll()
if ret is not None:
return ret
rs, ws, xs = select.select([pipe], (), (), timeout)
if not rs:
print('subprocess met network problem, killing...', file=sys.stderr)
os.kill(-p.pid, 15)
else:
os.read(pipe, 1024)
except KeyboardInterrupt:
os.kill(-p.pid, 15)
return -1
if __name__ == '__main__':
try:
import setproctitle
setproctitle.setproctitle('killhung')
del setproctitle
except ImportError:
pass
sys.exit(main(sys.argv[1:]))

Python 果然快准狠 ^_^

代码在 winterpy 仓库里也有一份

这还是我编程时第一次用到进程组呢。没办法,光杀 strace 进程没效果。嗯,还有非阻塞的命名管道


PS: 去 GMail 设置页看完那个选项的具体名字后离开,结果遇到这个:

cancel_cancel.png

你这是让我「确定更改」呢还是「取消取消更改」呢……


Recommend

  • 67

    公众号已经老了,小程序永远年轻-36氪公众号已经老了,小程序永远年轻36氪的朋友们·2017-12-15 07:33年轻的小程序代表着微信的未来。...

  • 101

    别再纠结logo的大小了,1个原则3种做法让广告效果加倍!-鸟哥笔记 首页 >...

  • 90

    还在纠结 Python 的数据导入问题吗?有这张速查表就够啦

  • 61
    • 新浪科技 tech.sina.com.cn 6 years ago
    • Cache

    在iPhone X和Galaxy S9之间纠结?注意这五点差别

    新浪科技讯北京时间2月26日上午消息,当微软发布Windows8的后继系统的时候,他们跳过了数字9,而直接发布了Windows10。而另一家科技巨头苹果也采取了相似的产品命名方式,他们在2017年发布了iPhone8/Plus和iPhone

  • 98

    Android - @heqet - 好纠结啊~请各位帮我选择一下,最怕的问题就是屏幕滑动有拖影,这两部手机应该都没有这样的问题吧?如果两部都不好,请大家给我其他推荐,谢谢,好人一生平安

  • 66
    • www.v2ex.com 6 years ago
    • Cache

    离职的纠结。。。 - V2EX

    职场话题 - @815lbh - 在这家公司整整两年吧,上月过年回来第二天就提了离职。公司这边一直含糊,挽留。其实吧,公司说加薪 20%。刚好到了我下一份工作的要求。其实公司还是很不错的,不加班双休,按时发工资,年底双薪。

  • 302
    • www.v2ex.com 6 years ago
    • Cache

    在纠结要不要自己做晚饭?

    问与答 - @tuding - 前提:已婚,暂时没有小孩,父母在老家。我几乎不加班,老婆经常加班。如果做晚饭,确实挺浪费时间的,择菜炒菜洗碗收拾前后差不多要 2 个小时,本来晚上的时间就很紧,感觉一晚上没做啥时间就过去了。

  • 0
    • www.flydean.com 2 years ago
    • Cache

    网络标准之:永远是1.0版本的MIME

    无规矩不成方圆,无标准不成网络通信。正是在各种网络协议和标准的基础之上,才构建了我们现在流行的互联网。今天给大家介绍的就是一个网络标准格式,叫做MIME,它的全称是Multipurpose Internet Mail Extensions,翻译过来就是多用途Internet邮件扩展。 ...

  • 5

    V2EX  ›  程序员 纠结 flutter、uni-app,做小程序该选哪个?   KwanChen · 9 小时 41 分钟...

  • 2

    在上一篇我们了解了Linux下线程的相关概念。而本篇的主要内容是线程控制。线程控制包括线程的创建,线程的终止,线程等待等问题,以及线程分离和Linux常见线程安全问题。1.线程控制线程控制和我们之前学习过的进程控制类似,包括线程创建终...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK