Pattern: pausing/resuming goroutine?

I have a goroutine “process things”; from another goroutine, I want to send signal “resume processing things”, which means “if things are already processing, do nothing; otherwise, spawn processor”.

My current code works, but I wonder if there is a simpler pattern.

// this runs forever, resuming processing when signalled into
// the "this.resume" channel. Bursts of resume calls need to be supported
func (this *jobQueue) feedJobQueue() {
   stopped := make(chan struct{})
   running := false

   for {
      select {
      case <-this.resume:
         if running {
            continue;
         }
         running = true
         
         // process things!
         go func() {
            for {
               job := this.pullNextJob()
               if job == nil {
                  stopped <- struct{}{}
                  return
               }
               this.jobs <- *job
            }
         }()
      case <-stopped:
         running = false
      }
   }
}

“things to process” are added in bursts from multiple goroutines, and added to persistent store; each time new job is queued, notification is sent to this.resume; the processing itself, however, takes a long time; this.jobs queue is consumed slowly one by one.

I know this sounds a lot like persistent MQ queues, but there are many reasons why I don’t want to use that for this particular context.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.