dtstnjl898781429 2018-05-03 07:26
浏览 62

go例程中基于上下文的长时间运行循环的终止

I'm implementing a feature where I need to read files from a directory, parse and export them to a REST service at a regular interval. As part of the same I would like to gracefully handle the program termination (SIGKILL, SIGQUIT etc). Towards the same I would like to know how to implement Context based cancellation of process.

For executing the flow in regular interval I'm using gocron.

cmd/scheduler.go

func scheduleTask(){
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()
    s := gocron.NewScheduler()
    s.Every(10).Minutes().Do(processTask, ctx)
    s.RunAll()  // run immediate
    <-s.Start() // schedule
    for {
        select {
        case <-(ctx).Done():
            fmt.Print("context done")
            s.Remove(processTask)
            s.Clear()
            cancel()
        default:
        }
    }
}   
func processTask(ctx *context.Context){
  task.Export(ctx)
}

task/export.go

func Export(ctx *context.Context){
   pendingFiles, err := filepath.Glob("/tmp/pending/" + "*_task.json")
   //error handling
   //as there can be 100s of files, I would like to break the loop when context.Done() to return asap & clean up the resources here as well
   for _, fileName := range pendingFiles {

    exportItem(fileName string)
   }
}

func exportItem(fileName string){
    data, err := ReadFile(fileName)  //not shown here for brevity
    //err handling
    err = postHTTPData(string(data)) //not shown for brevity
    //err handling
}
  • 写回答

1条回答 默认 最新

  • doujiao6507 2018-05-03 14:06
    关注

    For the process management, I think the other component is the actual handling of signals, and managing the context from those signals.

    I'm not sure of the specifics of go-cron (they have an example showing some of these concepts on their github) but in general I think that the steps involved are:

    • Registration of os signals handler
    • Waiting to receive a signal
    • Canceling top level context in response to a signal

    Example:

    sigCh := make(chan os.Signal, 1)
    defer close(sigCh)
    signal.Notify(sigCh, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT)
    <-sigCh
    cancel()
    

    I'm not sure how this will look in the context of go-cron, but the context that the signal handling code cancels should be a parent of the context that the task and job is given.

    评论

报告相同问题?

悬赏问题

  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)