func newRunner(creds) { &ciRunner{ githubClient: newGithubClient(creds), githubCredentials: creds, // Note: buffered channel. Means that writes to `builds` will almost always return immediately, // unless we accumulate 100 builds in the queue. We don't have a good failure mode if that happens. // That's OK for now. builds: make(chan *event, 100), } } func main() { runner := newRunner() // background goroutine for doing one build at a time. go runner.startBuilder() for event := range server.Events { // this returns almost immediately runner.handleEvent(event) } } func (r *runner) startBuilder() { // Only one thing happening at a time here. for event := range r.builds { runBazelCommand(event) // etc. setCIStatusSuccess() } } func (r *runner) handleEvent(event) { setCIStatusPending() builds<-event }