add multi delta enumeration to collection tree

tests coming in follow-up PR
This commit is contained in:
ryanfkeepers 2023-11-29 13:49:19 -07:00
parent 14225ad616
commit 3ab500a7d8

View File

@ -277,8 +277,20 @@ func (c *Collections) populateTree(
ctx = clues.Add(ctx, "invalid_prev_delta", len(prevDeltaLink) == 0) ctx = clues.Add(ctx, "invalid_prev_delta", len(prevDeltaLink) == 0)
var ( var (
currDeltaLink = prevDeltaLink
driveID = ptr.Val(drv.GetId()) driveID = ptr.Val(drv.GetId())
el = errs.Local() el = errs.Local()
du pagers.DeltaUpdate
finished bool
hitLimit bool
)
for !hitLimit && !finished && el.Failure() == nil {
var (
pageCount int
pageItemCount int
hadReset bool
err error
) )
// TODO(keepers): to end in a correct state, we'll eventually need to run this // TODO(keepers): to end in a correct state, we'll eventually need to run this
@ -286,23 +298,27 @@ func (c *Collections) populateTree(
pager := c.handler.EnumerateDriveItemsDelta( pager := c.handler.EnumerateDriveItemsDelta(
ctx, ctx,
driveID, driveID,
prevDeltaLink, currDeltaLink,
api.CallConfig{ api.CallConfig{
Select: api.DefaultDriveItemProps(), Select: api.DefaultDriveItemProps(),
}) })
for page, reset, done := pager.NextPage(); !done; page, reset, done = pager.NextPage() { for page, reset, done := pager.NextPage(); !done; page, reset, done = pager.NextPage() {
if el.Failure() != nil { if el.Failure() != nil {
break return du, el.Failure()
} }
if reset { if reset {
counter.Inc(count.PagerResets) counter.Inc(count.PagerResets)
tree.reset() tree.reset()
c.resetStats() c.resetStats()
pageCount = 0
pageItemCount = 0
hadReset = true
} }
err := c.enumeratePageOfItems( err = c.enumeratePageOfItems(
ctx, ctx,
tree, tree,
drv, drv,
@ -312,6 +328,7 @@ func (c *Collections) populateTree(
errs) errs)
if err != nil { if err != nil {
if errors.Is(err, errHitLimit) { if errors.Is(err, errHitLimit) {
hitLimit = true
break break
} }
@ -324,8 +341,13 @@ func (c *Collections) populateTree(
// at the end of the loop so we don't request another page (pager.NextPage) // at the end of the loop so we don't request another page (pager.NextPage)
// before seeing we've passed the limit. // before seeing we've passed the limit.
if limiter.hitPageLimit(int(counter.Get(count.PagesEnumerated))) { if limiter.hitPageLimit(int(counter.Get(count.PagesEnumerated))) {
hitLimit = true
break break
} }
pageCount++
pageItemCount += len(page)
} }
// Always cancel the pager so that even if we exit early from the loop above // Always cancel the pager so that even if we exit early from the loop above
@ -333,11 +355,18 @@ func (c *Collections) populateTree(
// essentially a noop. // essentially a noop.
pager.Cancel() pager.Cancel()
du, err := pager.Results() du, err = pager.Results()
if err != nil { if err != nil {
return du, clues.Stack(err) return du, clues.Stack(err)
} }
currDeltaLink = du.URL
// 0 pages is never expected. We should at least have one (empty) page to
// consume. But checking pageCount == 1 is brittle in a non-helpful way.
finished = pageCount < 2 && pageItemCount == 0 && !hadReset
}
logger.Ctx(ctx).Infow("enumerated collection delta", "stats", counter.Values()) logger.Ctx(ctx).Infow("enumerated collection delta", "stats", counter.Values())
return du, el.Failure() return du, el.Failure()