Skip to content

Instantly share code, notes, and snippets.

@kikuchy
Last active July 5, 2023 15:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kikuchy/72bfb219f95977f3d8cf6000d7f02016 to your computer and use it in GitHub Desktop.
Save kikuchy/72bfb219f95977f3d8cf6000d7f02016 to your computer and use it in GitHub Desktop.
Simple JobQueue for goroutines.
import "sync"
type JobQueue struct {
limit int
wg sync.WaitGroup
mu sync.Mutex
running int
waiting []func()
}
func NewJobQueue(limit int) *JobQueue {
return &JobQueue{limit: limit, running: 0}
}
func (q *JobQueue) Enqueue(job func()) {
q.wg.Add(1)
wrapper := func() {
defer q.wg.Done()
defer func() {
q.mu.Lock()
q.running -= 1
q.mu.Unlock()
q.reschedule()
}()
job()
}
q.waiting = append(q.waiting, wrapper)
q.reschedule()
}
func (q *JobQueue) reschedule() {
if len(q.waiting) > 0 && q.running < q.limit {
q.mu.Lock()
defer q.mu.Unlock()
first := q.waiting[0]
q.waiting = q.waiting[1:]
q.running += 1
go first()
}
}
func (q *JobQueue) Wait() {
q.wg.Wait()
}
// func main() {
// queue := NewJobQueue(2)
// for i := 0; i < 9; i++ {
// queue.Enqueue(func() {
// time.Sleep(time.Second)
// t := time.Now()
// fmt.Printf("Job %v\n", t)
// })
// }
// queue.Wait()
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment