"context"
"sort"
"sync"
+ "sync/atomic"
"git.curoverse.com/arvados.git/sdk/go/arvados"
)
func (conn *Conn) ContainerList(ctx context.Context, options arvados.ListOptions) (arvados.ContainerList, error) {
var mtx sync.Mutex
var merged arvados.ContainerList
+ var needSort atomic.Value
+ needSort.Store(false)
err := conn.splitListRequest(ctx, options, func(ctx context.Context, _ string, backend arvados.API, options arvados.ListOptions) ([]string, error) {
cl, err := backend.ContainerList(ctx, options)
if err != nil {
defer mtx.Unlock()
if len(merged.Items) == 0 {
merged = cl
- } else {
+ } else if len(cl.Items) > 0 {
merged.Items = append(merged.Items, cl.Items...)
+ needSort.Store(true)
}
uuids := make([]string, 0, len(cl.Items))
for _, item := range cl.Items {
}
return uuids, nil
})
- sort.Slice(merged.Items, func(i, j int) bool { return merged.Items[i].UUID < merged.Items[j].UUID })
+ if needSort.Load().(bool) {
+ // Apply the default/implied order, "modified_at desc"
+ sort.Slice(merged.Items, func(i, j int) bool {
+ mi, mj := merged.Items[i].ModifiedAt, merged.Items[j].ModifiedAt
+ if mi == nil || mj == nil {
+ return false
+ } else {
+ return mj.Before(*mi)
+ }
+ })
+ }
return merged, err
}
func (conn *Conn) SpecimenList(ctx context.Context, options arvados.ListOptions) (arvados.SpecimenList, error) {
var mtx sync.Mutex
var merged arvados.SpecimenList
+ var needSort atomic.Value
+ needSort.Store(false)
err := conn.splitListRequest(ctx, options, func(ctx context.Context, _ string, backend arvados.API, options arvados.ListOptions) ([]string, error) {
cl, err := backend.SpecimenList(ctx, options)
if err != nil {
defer mtx.Unlock()
if len(merged.Items) == 0 {
merged = cl
- } else {
+ } else if len(cl.Items) > 0 {
merged.Items = append(merged.Items, cl.Items...)
+ needSort.Store(true)
}
uuids := make([]string, 0, len(cl.Items))
for _, item := range cl.Items {
}
return uuids, nil
})
- sort.Slice(merged.Items, func(i, j int) bool { return merged.Items[i].UUID < merged.Items[j].UUID })
+ if needSort.Load().(bool) {
+ // Apply the default/implied order, "modified_at desc"
+ sort.Slice(merged.Items, func(i, j int) bool {
+ mi, mj := merged.Items[i].ModifiedAt, merged.Items[j].ModifiedAt
+ if mi == nil || mj == nil {
+ return false
+ } else {
+ return mj.Before(*mi)
+ }
+ })
+ }
return merged, err
}
"net/http"
"sort"
"sync"
+ "sync/atomic"
"git.curoverse.com/arvados.git/sdk/go/arvados"
"git.curoverse.com/arvados.git/sdk/go/httpserver"
func (conn *Conn) CollectionList(ctx context.Context, options arvados.ListOptions) (arvados.CollectionList, error) {
var mtx sync.Mutex
var merged arvados.CollectionList
+ var needSort atomic.Value
+ needSort.Store(false)
err := conn.splitListRequest(ctx, options, func(ctx context.Context, _ string, backend arvados.API, options arvados.ListOptions) ([]string, error) {
cl, err := backend.CollectionList(ctx, options)
if err != nil {
defer mtx.Unlock()
if len(merged.Items) == 0 {
merged = cl
- } else {
+ } else if len(cl.Items) > 0 {
merged.Items = append(merged.Items, cl.Items...)
+ needSort.Store(true)
}
uuids := make([]string, 0, len(cl.Items))
for _, item := range cl.Items {
}
return uuids, nil
})
- sort.Slice(merged.Items, func(i, j int) bool { return merged.Items[i].UUID < merged.Items[j].UUID })
+ if needSort.Load().(bool) {
+ // Apply the default/implied order, "modified_at desc"
+ sort.Slice(merged.Items, func(i, j int) bool {
+ mi, mj := merged.Items[i].ModifiedAt, merged.Items[j].ModifiedAt
+ if mi == nil || mj == nil {
+ return false
+ } else {
+ return mj.Before(*mi)
+ }
+ })
+ }
return merged, err
}
"net/http"
"net/url"
"os"
+ "sort"
"testing"
"git.curoverse.com/arvados.git/lib/controller/router"
for _, uuid := range trial.expectUUIDs {
expectItems = append(expectItems, arvados.Collection{UUID: uuid})
}
+ // expectItems is sorted by UUID, so sort resp.Items
+ // by UUID before checking DeepEquals.
+ sort.Slice(resp.Items, func(i, j int) bool { return resp.Items[i].UUID < resp.Items[j].UUID })
c.Check(resp, check.DeepEquals, arvados.CollectionList{
Items: expectItems,
})