X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/e502060ffe4f68d33e2cca8f8d7544ce40d53eb7..b49229f98012d7c08ce02b8d28dbcc165c8a6c53:/services/keep-balance/collection.go diff --git a/services/keep-balance/collection.go b/services/keep-balance/collection.go index a7a484672a..c4ddc90c41 100644 --- a/services/keep-balance/collection.go +++ b/services/keep-balance/collection.go @@ -1,10 +1,14 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + package main import ( "fmt" "time" - "git.curoverse.com/arvados.git/sdk/go/arvados" + "git.arvados.org/arvados.git/sdk/go/arvados" ) func countCollections(c *arvados.Client, params arvados.ResourceListParams) (int, error) { @@ -32,23 +36,37 @@ func EachCollection(c *arvados.Client, pageSize int, f func(arvados.Collection) } expectCount, err := countCollections(c, arvados.ResourceListParams{ - IncludeTrash: true, + IncludeTrash: true, + IncludeOldVersions: true, }) if err != nil { return err } + // Note the obvious way to get all collections (sorting by + // UUID) would be much easier, but would lose data: If a + // client were to move files from collection with uuid="zzz" + // to a collection with uuid="aaa" around the time when we + // were fetching the "mmm" page, we would never see those + // files' block IDs at all -- even if the client is careful to + // save "aaa" before saving "zzz". + // + // Instead, we get pages in modified_at order. Collections + // that are modified during the run will be re-fetched in a + // subsequent page. + limit := pageSize if limit <= 0 { // Use the maximum page size the server allows limit = 1<<31 - 1 } params := arvados.ResourceListParams{ - Limit: &limit, - Order: "modified_at, uuid", - Count: "none", - Select: []string{"uuid", "unsigned_manifest_text", "modified_at", "portable_data_hash", "replication_desired"}, - IncludeTrash: true, + Limit: &limit, + Order: "modified_at, uuid", + Count: "none", + Select: []string{"uuid", "unsigned_manifest_text", "modified_at", "portable_data_hash", "replication_desired"}, + IncludeTrash: true, + IncludeOldVersions: true, } var last arvados.Collection var filterTime time.Time @@ -62,7 +80,7 @@ func EachCollection(c *arvados.Client, pageSize int, f func(arvados.Collection) return err } for _, coll := range page.Items { - if last.ModifiedAt != nil && *last.ModifiedAt == *coll.ModifiedAt && last.UUID >= coll.UUID { + if last.ModifiedAt == coll.ModifiedAt && last.UUID >= coll.UUID { continue } callCount++ @@ -74,9 +92,9 @@ func EachCollection(c *arvados.Client, pageSize int, f func(arvados.Collection) } if len(page.Items) == 0 && !gettingExactTimestamp { break - } else if last.ModifiedAt == nil { + } else if last.ModifiedAt.IsZero() { return fmt.Errorf("BUG: Last collection on the page (%s) has no modified_at timestamp; cannot make progress", last.UUID) - } else if len(page.Items) > 0 && *last.ModifiedAt == filterTime { + } else if len(page.Items) > 0 && last.ModifiedAt == filterTime { // If we requested time>=X and never got a // time>X then we might not have received all // items with time==X yet. Switch to @@ -117,7 +135,7 @@ func EachCollection(c *arvados.Client, pageSize int, f func(arvados.Collection) // avoiding that would add overhead in the // overwhelmingly common cases, so we don't // bother. - filterTime = *last.ModifiedAt + filterTime = last.ModifiedAt params.Filters = []arvados.Filter{{ Attr: "modified_at", Operator: ">=", @@ -136,7 +154,8 @@ func EachCollection(c *arvados.Client, pageSize int, f func(arvados.Collection) Attr: "modified_at", Operator: "<=", Operand: filterTime}}, - IncludeTrash: true, + IncludeTrash: true, + IncludeOldVersions: true, }); err != nil { return err } else if callCount < checkCount {