zoukankan      html  css  js  c++  java
  • golang 定时器

    上网查了下相关资料,基本上都介绍的是github.com obfigcron这个包来执行定时任务,试了下确实可以执行。但是此包下没有删 除任务的方法,只有暂停的方法(Stop),若要停止之前的任务只执行新定义的任务,除非服务器重启再定义新任务。后来又参考了一下其他人的建议,采用了 github.comjakecoffmancron这个包。后者是在前者的基础上做了一定的修改,给每个任务添加的一个新属性Name,然后新添加 一个remove(name)方法,用来删除指定名字的任务,经测试使用后可正常删除任务,只不过之前的计划任务名得新建一个全局变量来存储。

    以下先简单介绍下定义时间集合的信息:

    字段名 是否必须 允许的值 允许的特定字符
    秒(Seconds) 0-59
    * / , -
    分(Minutes) 0-59
    * / , -
    时(Hours) 0-23
    * / , -
    日(Day of month) 1-31
    * / , – ?
    月(Month) 1-12 or JAN-DEC
    * / , -
    星期(Day of week) 0-6 or SUM-SAT
    * / , – ?

    注:
    1)月(Month)和星期(Day of week)字段的值不区分大小写,如:SUN、Sun 和 sun 是一样的。
    2)星期
    (Day of week)字段如果没提供,相当于是 *


    2、特殊字符说明
    1)星号(*)
    表示 cron 表达式能匹配该字段的所有值。如在第5个字段使用星号(month),表示每个月


    回到顶部
    2)斜线(/)
    表示增长间隔,如第1个字段(minutes) 值是 3-59/15,表示每小时的第3分钟开始执行一次,之后每隔 15 分钟执行一次(即 3、18、33、48 这些时间点执行),这里也可以表示为:3/15


    回到顶部
    3)逗号(,)
    用于枚举值,如第6个字段值是 MON,WED,FRI,表示 星期一、三、五 执行


    回到顶部
    4)连字号(-)
    表示一个范围,如第3个字段的值为 9-17 表示 9am 到 5pm 直接每个小时(包括9和17)


    回到顶部
    5)问号(?)
    只用于 日(Day of month) 和 星期(Day of week),表示不指定值,可以用于代替 *


    在beego下使用,我简单的封装一下(代码不是我写的,而且写的很随意,也只保证了可用的程度),自定义package jobs如下:

    job.go源码:

    1. package jobs  
    2.   
    3. import (  
    4.     "github.com/astaxie/beego"  
    5.     "github.com/jakecoffman/cron"  
    6.     "reflect"  
    7.     "runtime/debug"  
    8.     "sync"  
    9.     "sync/atomic"  
    10. )  
    11.   
    12. type Job struct {  
    13.     Name    string  
    14.     inner   cron.Job  
    15.     status  uint32  
    16.     running sync.Mutex  
    17. }  
    18.   
    19. const UNNAMED = "(unnamed)"  
    20.   
    21. func New(job cron.Job) *Job {  
    22.     name := reflect.TypeOf(job).Name()  
    23.     if name == "Func" {  
    24.         name = UNNAMED  
    25.     }  
    26.     return &Job{  
    27.         Name:  name,  
    28.         inner: job,  
    29.     }  
    30. }  
    31.   
    32. func (j *Job) Status() string {  
    33.     if atomic.LoadUint32(&j.status) > 0 {  
    34.         return "RUNNING"  
    35.     }  
    36.     return "IDLE"  
    37. }  
    38.   
    39. func (j *Job) Run() {  
    40.     // If the job panics, just print a stack trace.  
    41.     // Don't let the whole process die.  
    42.     defer func() {  
    43.         if err := recover(); err != nil {  
    44.             beego.Error("%v", debug.Stack())  
    45.         }  
    46.     }()  
    47.   
    48.     if !selfConcurrent {  
    49.         j.running.Lock()  
    50.         defer j.running.Unlock()  
    51.     }  
    52.   
    53.     if workPermits != nil {  
    54.         workPermits <- struct{}{}  
    55.         defer func() { <-workPermits }()  
    56.     }  
    57.   
    58.     atomic.StoreUint32(&j.status, 1)  
    59.     defer atomic.StoreUint32(&j.status, 0)  
    60.   
    61.     j.inner.Run()  
    62. }  

    jobrunner.go源码:

    1. // A job runner for executing scheduled or ad-hoc tasks asynchronously from HTTP requests.  
    2. //  
    3. // It adds a couple of features on top of the cron package to make it play nicely with Revel:  
    4. // 1. Protection against job panics.  (They print to ERROR instead of take down the process)  
    5. // 2. (Optional) Limit on the number of jobs that may run simulatenously, to  
    6. //    limit resource consumption.  
    7. // 3. (Optional) Protection against multiple instances of a single job running  
    8. //    concurrently.  If one execution runs into the next, the next will be queued.  
    9. // 4. Cron expressions may be defined in app.conf and are reusable across jobs.  
    10. // 5. Job status reporting.  
    11. package jobs  
    12.   
    13. import (  
    14.     //"fmt"  
    15.     "github.com/jakecoffman/cron"  
    16.     "time"  
    17. )  
    18.   
    19. // Callers can use jobs.Func to wrap a raw func.  
    20. // (Copying the type to this package makes it more visible)  
    21. //  
    22. // For example:  
    23. //    jobs.Schedule("cron.frequent", jobs.Func(myFunc))  
    24. type Func func()  
    25.   
    26. func (r Func) Run() { r() }  
    27.   
    28. //定时执行任务  
    29. func Schedule(spec string, job cron.Job, name string) error {  
    30.     sched := cron.Parse(spec)  
    31.     /*if err != nil {  
    32.         return err  
    33.     }*/  
    34.     MainCron.Schedule(sched, New(job), name)  
    35.     return nil  
    36. }  
    37.   
    38. // Run the given job at a fixed interval.  
    39. // The interval provided is the time between the job ending and the job being run again.  
    40. // The time that the job takes to run is not included in the interval.  
    41. func Every(duration time.Duration, job cron.Job, name string) {  
    42.     MainCron.Schedule(cron.Every(duration), New(job), name)  
    43. }  
    44.   
    45. // Run the given job right now.  
    46. func Now(job cron.Job) {  
    47.     go New(job).Run()  
    48. }  
    49.   
    50. // Run the given job once, after the given delay.  
    51. func In(duration time.Duration, job cron.Job) {  
    52.     go func() {  
    53.         time.Sleep(duration)  
    54.         New(job).Run()  
    55.     }()  
    56. }  
    57.   
    58. // 暂停所有任务  
    59. func Stop() {  
    60.     MainCron.Stop()  
    61. }  
    62.   
    63. //清空任务  
    64. func Remove(name string) {  
    65.     MainCron.RemoveJob(name)  
    66. }  

    plugin.go源码:

    1. package jobs  
    2.   
    3. import (  
    4.     "github.com/jakecoffman/cron"  
    5. )  
    6.   
    7. const DEFAULT_JOB_POOL_SIZE = 10  
    8.   
    9. var (  
    10.     // Singleton instance of the underlying job scheduler.  
    11.     MainCron *cron.Cron  
    12.   
    13.     // This limits the number of jobs allowed to run concurrently.  
    14.     workPermits chan struct{}  
    15.   
    16.     // Is a single job allowed to run concurrently with itself?  
    17.     selfConcurrent bool  
    18. )  
    19.   
    20. func init() {  
    21.     MainCron = cron.New()  
    22.     workPermits = make(chan struct{}, DEFAULT_JOB_POOL_SIZE)  
    23.     selfConcurrent = false  
    24.     MainCron.Start()  
    25. }  

    因为是网站执行定时任务,这边我是将任务是否开启的控制权放在前端页面,通过点击按钮访问controller方法,从而启动任务,所以我把任务执行方法放在了controller中。通过如下方式调用:

    1. import (  
    2.     //其他引用包我都省略了  
    3.     "hnnaserver/src/jobs"  
    4. )  
    5.   
    6. type job struct {  
    7.     user     string  
    8.     province int64  
    9.     method   int64  
    10.     count    int64  
    11. }  
    12.   
    13. //任务执行的方法  
    14. func (j *job) Run() {  
    15.     //do something....  
    16. }  
    17.   
    18. func (this *SystemController) AutoDisCus() {  
    19.     spec := "0 0 15 * * 1-5"//定义执行时间点 参照上面的说明可知 执行时间为 周一至周五每天15:00:00执行  
    20.     //spec := "*/5 * * * * ?" //这是网上一般的例子 即每5s执行一次  
    21.     j := &job{user, province, method, count}  
    22.     jobs.Schedule(spec, j, taskName) //3个参数分别为 执行时间(规则之间介绍过) 要执行的任务  任务名  
    23. }  

    若要删除某项任务,则调用remove方法即可,如下:

      1. jobs.Remove(tasksName) 
  • 相关阅读:
    帮助智力障碍的可怜儿童
    PE556
    ZJOIDay2T1 BB题解
    CTSC2016游记
    再次被老爸钦点退役
    欧拉筛
    考据
    51nod 1020 逆序排列(动态规划)
    51nod 1186 质数检测(Miller-Rabin算法)
    大整数类模板
  • 原文地址:https://www.cnblogs.com/zhangym/p/5760324.html
Copyright © 2011-2022 走看看