api: remove items deleted during refresh pagination (#5056)
The API automatically paginates to the end of a pagination, and would take into account any items updated and subsequently removed since the last pagination. It now also removes any items removed during the current pagination.
This commit is contained in:
1 parent
84707c04cb
commit
4a031d9910
23 files changed
+302
-279
No files matched your search
+13
-12
@@ -64,9 +64,6 @@ func (c *Client) ListResolvableAliases(ctx context.Context, userId string, opt .
|
||||
for i, item := range target.Items {
|
||||
idToIndex[item.Id] = i
|
||||
}
|
||||
// Removed IDs in the response may contain duplicates,
|
||||
// maintain a set to avoid returning duplicates to the user.
|
||||
removedIds := map[string]struct{}{}
|
||||
for {
|
||||
req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("users/%s:list-resolvable-aliases", url.PathEscape(userId)), nil, apiOpts...)
|
||||
if err != nil {
|
||||
@@ -104,9 +101,8 @@ func (c *Client) ListResolvableAliases(ctx context.Context, userId string, opt .
|
||||
idToIndex[item.Id] = len(target.Items) - 1
|
||||
}
|
||||
}
|
||||
for _, removedId := range page.RemovedIds {
|
||||
removedIds[removedId] = struct{}{}
|
||||
}
|
||||
// RemovedIds contain any Alias that were deleted since the last response.
|
||||
target.RemovedIds = append(target.RemovedIds, page.RemovedIds...)
|
||||
target.EstItemCount = page.EstItemCount
|
||||
target.ListToken = page.ListToken
|
||||
target.ResponseType = page.ResponseType
|
||||
@@ -115,21 +111,26 @@ func (c *Client) ListResolvableAliases(ctx context.Context, userId string, opt .
|
||||
break
|
||||
}
|
||||
}
|
||||
// For now, removedIds will only be populated if this pagination cycle was the result of a
|
||||
// "refresh" operation (i.e., the caller provided a list token option to this call).
|
||||
//
|
||||
// Sort to make response deterministic
|
||||
slices.Sort(target.RemovedIds)
|
||||
// Remove any duplicates
|
||||
target.RemovedIds = slices.Compact(target.RemovedIds)
|
||||
// Remove items that were deleted since the end of the last iteration.
|
||||
// If an Alias has been updated and subsequently removed, we don't want
|
||||
// it to appear both in the Items and RemovedIds, so we remove it from the Items.
|
||||
for _, removedId := range target.RemovedIds {
|
||||
if i, ok := idToIndex[removedId]; ok {
|
||||
// Remove the item at index i without preserving order
|
||||
// https://github.com/golang/go/wiki/SliceTricks#delete-without-preserving-order
|
||||
target.Items[i] = target.Items[len(target.Items)-1]
|
||||
target.Items = target.Items[:len(target.Items)-1]
|
||||
// Update the index of the last element
|
||||
// Update the index of the previously last element
|
||||
idToIndex[target.Items[i].Id] = i
|
||||
}
|
||||
}
|
||||
for deletedId := range removedIds {
|
||||
target.RemovedIds = append(target.RemovedIds, deletedId)
|
||||
}
|
||||
// Sort to make response deterministic
|
||||
slices.Sort(target.RemovedIds)
|
||||
// Since we paginated to the end, we can avoid confusion
|
||||
// for the user by setting the estimated item count to the
|
||||
// length of the items slice. If we don't set this here, it
|
||||
|
||||
+13
-12
@@ -354,9 +354,6 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*User
|
||||
for i, item := range target.Items {
|
||||
idToIndex[item.Id] = i
|
||||
}
|
||||
// Removed IDs in the response may contain duplicates,
|
||||
// maintain a set to avoid returning duplicates to the user.
|
||||
removedIds := map[string]struct{}{}
|
||||
for {
|
||||
req, err := c.client.NewRequest(ctx, "GET", "users", nil, apiOpts...)
|
||||
if err != nil {
|
||||
@@ -394,9 +391,8 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*User
|
||||
idToIndex[item.Id] = len(target.Items) - 1
|
||||
}
|
||||
}
|
||||
for _, removedId := range page.RemovedIds {
|
||||
removedIds[removedId] = struct{}{}
|
||||
}
|
||||
// RemovedIds contain any User that were deleted since the last response.
|
||||
target.RemovedIds = append(target.RemovedIds, page.RemovedIds...)
|
||||
target.EstItemCount = page.EstItemCount
|
||||
target.ListToken = page.ListToken
|
||||
target.ResponseType = page.ResponseType
|
||||
@@ -405,21 +401,26 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*User
|
||||
break
|
||||
}
|
||||
}
|
||||
// For now, removedIds will only be populated if this pagination cycle was the result of a
|
||||
// "refresh" operation (i.e., the caller provided a list token option to this call).
|
||||
//
|
||||
// Sort to make response deterministic
|
||||
slices.Sort(target.RemovedIds)
|
||||
// Remove any duplicates
|
||||
target.RemovedIds = slices.Compact(target.RemovedIds)
|
||||
// Remove items that were deleted since the end of the last iteration.
|
||||
// If a User has been updated and subsequently removed, we don't want
|
||||
// it to appear both in the Items and RemovedIds, so we remove it from the Items.
|
||||
for _, removedId := range target.RemovedIds {
|
||||
if i, ok := idToIndex[removedId]; ok {
|
||||
// Remove the item at index i without preserving order
|
||||
// https://github.com/golang/go/wiki/SliceTricks#delete-without-preserving-order
|
||||
target.Items[i] = target.Items[len(target.Items)-1]
|
||||
target.Items = target.Items[:len(target.Items)-1]
|
||||
// Update the index of the last element
|
||||
// Update the index of the previously last element
|
||||
idToIndex[target.Items[i].Id] = i
|
||||
}
|
||||
}
|
||||
for deletedId := range removedIds {
|
||||
target.RemovedIds = append(target.RemovedIds, deletedId)
|
||||
}
|
||||
// Sort to make response deterministic
|
||||
slices.Sort(target.RemovedIds)
|
||||
// Since we paginated to the end, we can avoid confusion
|
||||
// for the user by setting the estimated item count to the
|
||||
// length of the items slice. If we don't set this here, it
|
||||
|
||||
Reference in new issue
Block a user