// allGCPPrinters calls gcp.List, then calls gcp.Printer, one goroutine per // printer. This is a fast way to fetch all printers with corresponding CDD // info, which the List API does not provide. // // The second return value is a map of GCPID -> queued print job quantity. func allGCPPrinters(gcp *gcp.GoogleCloudPrint) ([]lib.Printer, map[string]uint, error) { ids, err := gcp.List() if err != nil { return nil, nil, err } type response struct { printer *lib.Printer queuedJobsCount uint err error } ch := make(chan response) for id := range ids { go func(id string) { printer, queuedJobsCount, err := gcp.Printer(id) ch <- response{printer, queuedJobsCount, err} }(id) } errs := make([]error, 0) printers := make([]lib.Printer, 0, len(ids)) queuedJobsCount := make(map[string]uint) for _ = range ids { r := <-ch if r.err != nil { errs = append(errs, r.err) continue } printers = append(printers, *r.printer) if r.queuedJobsCount > 0 { queuedJobsCount[r.printer.GCPID] = r.queuedJobsCount } } if len(errs) == 0 { return printers, queuedJobsCount, nil } else if len(errs) == 1 { return nil, nil, errs[0] } else { // Return an error that is somewhat human-readable. b := bytes.NewBufferString(fmt.Sprintf("%d errors: ", len(errs))) for i, err := range errs { if i > 0 { b.WriteString(", ") } b.WriteString(err.Error()) } return nil, nil, errors.New(b.String()) } }