使用gevent spawn_later实现定时计划任务系统

前段时间用有优先级和线程池做了可控的计划任务模块。正好今还在看gevent wsgi的东西,在想用gevent能不能实现计划任务系统。 看了下gevent的文档,发现他没有现成那样的timer功能,但是有个spawn_later的功能。 spawn_later函数可接收周期时间及运行函数。 

简单说,用gevent.spawn_later就可以实现crontab的效果…..


python gevent开发定时任务系统,原文地址是,http://xiaorui.cc/?p=2032



#coding:utf-8
import gevent
import gevent.monkey

gevent.monkey.patch_all()

INTERVAL = 10

def schedule(delay, func, *args, **kw_args):
    gevent.spawn_later(0, func, *args, **kw_args)
    gevent.spawn_later(delay, schedule, delay, func, *args, **kw_args)

def test1():
    print "func test1"

def test2():
    print "func test2"

def test3():
    print "test3"

schedule(1,test1)
schedule(2,test2)
schedule(3,test3)

while 1:
    gevent.sleep(1)

我前两天用gevent spawn_later函数,做了个小定时任务系统。

项目我已经推送到github上了, https://github.com/rfyiamcool/GeventCron

GeventCron

原理:

gevent cron是一个利用gevent开发的定时任务系统,模块不大,五藏俱全,还支持动态的添加任务和关闭任务.

他的缺点就是,太依赖gevent的调度了,所以如果你逻辑里面采用的是堵塞模块,那么定时任务的执行时间都要乱掉…..所以尽量让你业务逻辑,采用gevent patch过的模块。比如subprocess,换成gevent subprocess .

使用方法:

#coding:utf-8
import geventcron 
from datetime import datetime
import time
import os
import requests

def func_1():
    time.sleep(2)

def func_2():
    time.sleep(2)

def func_3():
    time.sleep(2)

if __name__ == "__main__":
    scheduler = geventcron.Scheduler(logger_name='task_scheduler')
    scheduler.schedule('task_1', geventsheduler.every_second(4), func_1)
    scheduler.schedule('task_2', geventsheduler.every_second(1), func_2)
    scheduler.schedule('task_3', geventsheduler.every_second(1), func_3)
    scheduler.run_forever(start_at='once')

主要的事情说三遍,不要用让gevent阻塞的模块,不要用堵塞的模块,不要用堵塞的模块... O(∩_∩)O~

(这两天有人用了我这模块发生了io堵塞.... )


下次我会把线上正在使用的定时任务系统,分享下。。。 功能很像celery,rq那样,把函数跟类字符串化,支持线程、进程选择。


大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码,感谢!
另外再次标注博客原地址  xiaorui.cc

4 Responses

  1. bug反馈 2016年11月21日 / 上午11:08

    大兄弟,我提了一个问题,有时间的话回复我一下吧,我先吧waiting去掉了:https://github.com/rfyiamcool/GeventCron/issues/1;我的邮箱:pengyusong2012@126.com

  2. gg 2015年10月22日 / 下午3:54

    涉及到阻塞咋办好,把executor作为服务独立出来?

发表评论

邮箱地址不会被公开。 必填项已用*标注