title: Context based termination of long running loop in a go routine
body: <p>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.</p>
  
  <p>For executing the flow in regular interval I'm using gocron.</p>
  
  <h2>cmd/scheduler.go</h2>
  
  <pre><code>func scheduleTask(){
      ctx, cancel := context.WithCancel(context.Background())
      defer cancel()
      s := gocron.NewScheduler()
      s.Every(10).Minutes().Do(processTask, ctx)
      s.RunAll()  // run immediate
      &lt;-s.Start() // schedule
      for {
          select {
          case &lt;-(ctx).Done():
              fmt.Print("context done")
              s.Remove(processTask)
              s.Clear()
              cancel()
          default:
          }
      }
  }   
  func processTask(ctx *context.Context){
    task.Export(ctx)
  }
  </code></pre>
  
  <h2>task/export.go</h2>
  
  <pre><code>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 &amp; 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
  }
  </code></pre>