简体   繁体   中英

Why golang CronJob cannot run within goroutine?

I use CronJob for starting my task everyday, and my task has several sub-tasks which I plan to use goroutine to run. However, things do not go smoothly.

File Framework

|-gpool
|  -pool.go
|-main.go

main.go

import (
        "code.byted.org/i18n_web/content_import_tool_cronJob/gpool"
        "fmt"
        "github.com/robfig/cron/v3"
        "log"
        "os"
        "runtime"
        "time"
    )
    
    func SeedJob(it string, pool *gpool.Pool){
        fmt.Println("Name item: ", it)
        println(runtime.NumGoroutine())
        pool.Done()
    }
    
    type delayJob struct {
        PagePatternNameList []string
    }
    
    func (j *delayJob) GetPagePatternNameList() {
        //j.PagePatternNameList = dal.GetPagePatternName()
        j.PagePatternNameList = []string{"atama_posts","cchan_posts", "cookdoor_posts", "cookpad_posts",
            "cookpad_recipe_seed", "kurashiru_posts", "lips_all_posts", "lips_product", "lips_product_sku_seed",
            "lips_rank", "press_posts", "voce_all_posts", "zozo_posts_women"}
    }
    
    func (j *delayJob)Run(){
        log.Println("delay Job RUN")
        //time.Sleep(2 * time.Second)
        // startSeedJob
        pool := gpool.New(10)
        println(runtime.NumGoroutine())
        for _, it := range j.PagePatternNameList {
            pool.Add(1)
            go SeedJob(it, pool)
        }
        pool.Wait()
        println(runtime.NumGoroutine())
    }
    
    func main() {
        c := cron.New(
            cron.WithLogger(
                cron.VerbosePrintfLogger(log.New(os.Stdout, "cron: ", log.LstdFlags))))
    
        _, err := c.AddJob("CRON_TZ=America/New_York @every 2m", cron.NewChain(cron.DelayIfStillRunning(cron.DefaultLogger)).Then(&delayJob{}))
        if err != nil {
            fmt.Println("Cron Job err!")
            return
        }
        fmt.Println("it started")
        c.Start()
    
        defer c.Stop()
    
        time.Sleep(time.Second * 5)
    
    }

pool.go

package gpool
    
    import (
        "sync"
    )
    
    type Pool struct {
        queue chan int
        wg    *sync.WaitGroup
    }
    
    func New(size int) *Pool {
        if size <= 0 {
            size = 1
        }
        return &Pool{
            queue: make(chan int, size),
            wg:    &sync.WaitGroup{},
        }
    }
    
    func (p *Pool) Add(delta int) {
        for i := 0; i < delta; i++ {
            p.queue <- 1
        }
        for i := 0; i > delta; i-- {
            <-p.queue
        }
        p.wg.Add(delta)
    }
    
    func (p *Pool) Done() {
        <-p.queue
        p.wg.Done()
    }
    
    func (p *Pool) Wait() {
        p.wg.Wait()
    }

When I run my code, it did not print out any information I expected, just

it started
cron: 2021/06/10 13:41:21 start
cron: 2021/06/10 13:41:21 schedule, now=2021-06-10T13:41:21+08:00, entry=1, next=2021-06-10T13:43:21+08:00
Exiting.

Debugger finished with the exit code 0

It seems like it did not trigger an err, but not run correctly. How can I solve this?

It did not run because you scheduled the job to run every 2 minutes and then waited only 5 seconds, then you returned from main() which causes your program to exit.

If you want to start this cron in the background you must keep the program running long enough for it to run and complete, at least more than 2 minutes in this example.

If you have nothing else to do in main() then you might consider using c.Run() rather than c.Start() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM