I ran into the classic “range over a channel” leak while working on a custom cron scheduler. I’ve debugged it on prod many times before, but writing one myself in a small piece of code reminded me how easy it is to write bugs like this even when you know about it. Here: on each tick, the scheduler dispatches the jobs that are due each job reports its outcome on a channel one collector ranges over that channel to record the run func tick(due []Job) []outcome { results := make(chan outcome) var wg sync.WaitGroup for _, j := range due { wg.Add(1) go func() { results <- outcome{job: j.Name, err: j.Run()} // (1) }() } var log []outcome go func() { for r := range results { // (2) log = append(log, r) wg.Done() } }() wg.Wait() // (3) no close(results) return log } (1) each due job sends its outcome on the unbuffered channel (2) the collector ranges over results, recording each outcome and marking it done (3) once every job has reported, wg.Wait unblocks and tick returns The producers are…
No comments yet. Log in to reply on the Fediverse. Comments will appear here.