func startJob(s *State, hc *cluster.Host, job *host.Job) error { jobStatus := make(chan error) events := make(chan *host.Event) stream, err := hc.StreamEvents(job.ID, events) if err != nil { return err } go func() { defer stream.Close() loop: for { select { case e, ok := <-events: if !ok { break loop } switch e.Event { case "start", "stop": jobStatus <- nil return case "error": job, err := hc.GetJob(job.ID) if err != nil { jobStatus <- err return } if job.Error == nil { jobStatus <- fmt.Errorf("bootstrap: unknown error from host") return } jobStatus <- fmt.Errorf("bootstrap: host error while launching job: %q", *job.Error) return default: } case <-time.After(30 * time.Second): jobStatus <- errors.New("bootstrap: timed out waiting for job event") return } } jobStatus <- fmt.Errorf("bootstrap: host job stream disconnected unexpectedly: %q", stream.Err()) }() if err := hc.AddJob(job); err != nil { return err } return <-jobStatus }
func startJob(s *State, hc *cluster.Host, job *host.Job) (*Job, error) { data := &Job{HostID: hc.ID(), JobID: job.ID} jobStatus := make(chan error) events := make(chan *host.Event) stream, err := hc.StreamEvents(data.JobID, events) if err != nil { return nil, err } go func() { defer stream.Close() for e := range events { switch e.Event { case "start", "stop": jobStatus <- nil return case "error": job, err := hc.GetJob(data.JobID) if err != nil { jobStatus <- err return } if job.Error == nil { jobStatus <- fmt.Errorf("bootstrap: unknown error from host") return } jobStatus <- fmt.Errorf("bootstrap: host error while launching job: %q", *job.Error) return default: } } jobStatus <- fmt.Errorf("bootstrap: host job stream disconnected unexpectedly: %q", stream.Err()) }() if err := hc.AddJob(job); err != nil { return nil, err } return data, <-jobStatus }