在python中创建处理队列

时间:2012-01-21 00:22:57

标签: python

我设置了一个电子邮件帐户,只要收到电子邮件,就会触发python脚本。该脚本经历了几个函数,这些函数可能需要大约30秒并将条目写入MYSQL数据库。

一切顺利进行,直到第一封电子邮件在第一封电子邮件发送后不到30秒内发送。第二封电子邮件处理正确,但第一封电子邮件会在数据库中创建损坏的条目。

我希望保留电子邮件数据,

msg=email.message_from_file(sys.stdin)
如果脚本尚未处理完之前的电子邮件,则在队列中

我正在使用python 2.5。 任何人都可以推荐一个可以实现此目的的包/脚本吗?

3 个答案:

答案 0 :(得分:2)

我会调查http://celeryproject.org/

我非常肯定会完全满足您的需求。

答案 1 :(得分:2)

我发现这是一种避免在前一个cronjob仍在运行时运行cronjob的简单方法。

fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) 

这会引发一个IOError,然后让进程自行处理。

有关详细信息,请参阅http://docs.python.org/library/fcntl.html#fcntl.lockf

无论如何,您可以轻松地使用相同的想法,只允许一次运行一个作业,这实际上与队列不同(因为任何等待的进程都可能获得锁定),但它实现了你的目标想。

import fcntl
import time
fd = open('lock_file', 'w')
fcntl.lockf(fd, fcntl.LOCK_EX)
# optionally write pid to another file so you have an indicator
# of the currently running process
print 'Hello'
time.sleep(1)

您也可以使用http://docs.python.org/dev/library/multiprocessing.html#exchanging-objects-between-processes,这正是您想要的。

答案 2 :(得分:2)

虽然Celery是一款非常精美的软件,但在这种情况下使用它类似于用大锤驱动钉子。在概念层面,您 正在寻找一个作业队列(这是芹菜提供的),但您用来触发脚本的电子邮件收件箱一个能力作业队列。

更直接的解决方案是让Python工作者脚本轮询邮件服务器本身(例如使用内置的poplib)每隔几秒检索一次所有新邮件,然后处理任何新的电子邮件。时间。这将序列化您的脚本正在执行的工作,从而防止一次运行两个副本。

例如,您可以将现有脚本包装在这样的函数中(来自上面链接的文档):

import getpass, poplib
from time import sleep

M = poplib.POP3('localhost')
M.user(getpass.getuser())
M.pass_(getpass.getpass())
while True:
    numMessages = len(M.list()[1])
    for i in range(numMessages):
        email = '\n'.join(M.retr(i+1)[1])
        # This is what your script normally does:
        do_work_for_message(email)
    sleep(5)

编辑:语法