//
// * len(Order)==0
//
-// * there are no filters other than the "uuid = ..." and "uuid in
-// ..." filters mentioned above.
+// * Each filter must be either "uuid = ..." or "uuid in [...]".
//
// * The maximum possible response size (total number of objects that
// could potentially be matched by all of the specified filters)
if matchAllFilters == nil {
matchAllFilters = matchThisFilter
} else {
- // matchAllFilters = intersect(matchAllFilters, matchThisFilter)
+ // Reduce matchAllFilters to the intersection
+ // of matchAllFilters ∩ matchThisFilter.
for uuid := range matchAllFilters {
if !matchThisFilter[uuid] {
delete(matchAllFilters, uuid)
}
}
+ // Collate UUIDs in matchAllFilters by remote cluster ID --
+ // e.g., todoByRemote["aaaaa"]["aaaaa-4zz18-000000000000000"]
+ // will be true -- and count the total number of UUIDs we're
+ // filtering on, so we can compare it to our max page size
+ // limit.
nUUIDs := 0
todoByRemote := map[string]map[string]bool{}
for uuid := range matchAllFilters {
if len(todoByRemote) > 1 {
if cannotSplit {
- return httpErrorf(http.StatusBadRequest, "cannot execute federated list query with filters other than 'uuid = ...' and 'uuid in [...]'")
+ return httpErrorf(http.StatusBadRequest, "cannot execute federated list query: each filter must be either 'uuid = ...' or 'uuid in [...]'")
}
if opts.Count != "none" {
return httpErrorf(http.StatusBadRequest, "cannot execute federated list query unless count==\"none\"")
defer cancel()
errs := make(chan error, len(todoByRemote))
for clusterID, todo := range todoByRemote {
- clusterID, todo := clusterID, todo
- batch := make([]string, 0, len(todo))
- for uuid := range todo {
- batch = append(batch, uuid)
- }
- go func() {
+ go func(clusterID string, todo map[string]bool) {
// This goroutine sends exactly one value to
// errs.
+ batch := make([]string, 0, len(todo))
+ for uuid := range todo {
+ batch = append(batch, uuid)
+ }
+
var backend arvados.API
if clusterID == conn.cluster.ClusterID {
backend = conn.local
}
}
errs <- nil
- }()
+ }(clusterID, todo)
}
// Wait for all goroutines to return, then return the first
// non-nil error, if any.
var firstErr error
- for i := 0; i < len(todoByRemote); i++ {
+ for range todoByRemote {
if err := <-errs; err != nil && firstErr == nil {
firstErr = err
// Signal to any remaining fn() calls that