code: func resolveServiceIDs(c context.Context, urls []string, out *identityset.Set) error {
  	// URL fetch calls below should be extra fast. If they get stuck, something is
  	// horribly wrong, better to abort soon.
  	c, abort := clock.WithTimeout(c, 5*time.Second)
  	defer abort()
  
  	type Result struct {
  		URL string
  		ID  identity.Identity
  		Err error
  	}
  
  	ch := make(chan Result, len(urls))
  
  	for _, url := range urls {
  		go func(url string) {
  			id, err := fetchLUCIServiceIdentity(c, url)
  			ch <- Result{url, id, err}
  		}(url)
  	}
  
  	for i := 0; i < len(urls); i++ {
  		result := <-ch
  		if result.Err != nil {
  			if transient.Tag.In(result.Err) {
  				return result.Err
  			}
  			return fmt.Errorf("could not resolve %q to service ID - %s", result.URL, result.Err)
  		}
  		out.AddIdentity(result.ID)
  	}
  
  	return nil
  }
docs: // resolveServiceIDs takes a bunch of service URLs and resolves them to
  // 'service:<app-id>' identities, putting them in the 'out' set.
  //
  // May return transient errors.