为了账号安全,请及时绑定邮箱和手机立即绑定

从 gocron 任务返回输出数据

从 gocron 任务返回输出数据

Go
森栏 2022-08-01 10:21:56
我使用调度程序,运行匿名函数:gocronj := Job{}j.ClientID = clientidj.Topic = topicj.Range = rangej.Interval = intervalj.Task = func(s string, t string){    fmt.Println(s)    fmt.Println(t)    Query_by_limit(s, t)// <-- data wanted}gocron.Every(j.Interval).Seconds().Do(j.Task, j.Topic, j.Range)gocron.Start()如何从每次到达时捕获数据并将其发送以进行处理?Query_by_limit()
查看完整描述

1 回答

?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

影响您要使用的解决方案的因素有很多。以下是在考虑如何继续之前需要回答的问题。

  • 您的图书馆如何运作?它是否同时执行作业,同时保持需要执行的作业的计划顺序?还是所有计划作业都在同一线程/goroutine 中执行?gocron

  • 您是否关心检索到的数据以何种顺序进行处理?是否需要按检索顺序处理它?

  • 是要立即处理数据,还是也在单独的计划作业中处理数据?

  • 数据处理所花费的时间是比两个计划作业之间的时间间隔的持续时间更多还是更少?

下面是一个解决方案,其假设是计划程序不同时执行任务(某些库以这种方式工作),数据处理永远不会超过作业等待间隔的持续时间,并且需要按检索顺序处理数据。gocron

queryJob := Job{}

dataCh := make(chan interface{}) 

done := make(chan bool)

queryJob.ClientID = clientid

queryJob.Topic = topic

queryJob.Range = range

queryJob.Interval = interval

queryJob.Task = func(s string, t string, dataCh chan<- interface{}){

    fmt.Println(s)

    fmt.Println(t)

    data, err := Query_by_limit(s, t)

    if err != nil {

      //handle error

    }

    dataCh <- data //if dataCh is an unbuffered channel, the job blocks here until the data is read in the data processing goroutine

    

}


//data processing goroutine

go func() {

  for data := range dataCh {

    //process data

  }

  done <-true

}()


gocron.Every(j.Interval).Seconds().Do(j.Task, j.Topic, j.Range, dataCh)

gocron.Start()

//when scheduler exits, you can close dataCh and give it a chance to be emptied

close(dataCh)

<-done

如果不想在数据处理 goroutine 中读取数据之前阻止作业,则可以将通道设置为缓冲通道。dataCh


如果数据处理花费的时间比计划作业的等待间隔长,并且您仍然希望保持需要处理的数据的顺序,则解决方案会变得更加复杂。如果要在不同的计划作业中处理数据,情况也是如此。在这些情况下,我建议尝试使用队列来存储和维护其中数据顺序的解决方案,以及在程序退出之前实现排出队列并处理所有数据。


查看完整回答
反对 回复 2022-08-01
  • 1 回答
  • 0 关注
  • 83 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信