mirror of
https://github.com/rclone/rclone.git
synced 2024-11-25 18:04:55 +01:00
zoho: use cursor listing for improved performance
Cursor listing enables us to list up to 1,000 items per call (previously it was 10) and uses one less transaction per call. See: https://forum.rclone.org/t/second-followup-on-the-older-topic-rclone-invokes-more-number-of-workdrive-s-files-listing-api-calls-which-exceeds-the-throttling-limit/45697/4
This commit is contained in:
parent
d068e0b1a9
commit
61c18e3b60
@ -70,8 +70,17 @@ type ItemInfo struct {
|
|||||||
Item Item `json:"data"`
|
Item Item `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Links contains Cursor information
|
||||||
|
type Links struct {
|
||||||
|
Cursor struct {
|
||||||
|
HasNext bool `json:"has_next"`
|
||||||
|
Next string `json:"next"`
|
||||||
|
} `json:"cursor"`
|
||||||
|
}
|
||||||
|
|
||||||
// ItemList contains multiple Zoho Items
|
// ItemList contains multiple Zoho Items
|
||||||
type ItemList struct {
|
type ItemList struct {
|
||||||
|
Links Links `json:"links"`
|
||||||
Items []Item `json:"data"`
|
Items []Item `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,18 +454,18 @@ type listAllFn func(*api.Item) bool
|
|||||||
//
|
//
|
||||||
// If the user fn ever returns true then it early exits with found = true
|
// If the user fn ever returns true then it early exits with found = true
|
||||||
func (f *Fs) listAll(ctx context.Context, dirID string, directoriesOnly bool, filesOnly bool, fn listAllFn) (found bool, err error) {
|
func (f *Fs) listAll(ctx context.Context, dirID string, directoriesOnly bool, filesOnly bool, fn listAllFn) (found bool, err error) {
|
||||||
|
const listItemsLimit = 1000
|
||||||
opts := rest.Opts{
|
opts := rest.Opts{
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
Path: "/files/" + dirID + "/files",
|
Path: "/files/" + dirID + "/files",
|
||||||
ExtraHeaders: map[string]string{"Accept": "application/vnd.api+json"},
|
ExtraHeaders: map[string]string{"Accept": "application/vnd.api+json"},
|
||||||
Parameters: url.Values{},
|
Parameters: url.Values{
|
||||||
|
"page[limit]": {strconv.Itoa(listItemsLimit)},
|
||||||
|
"page[next]": {"0"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
opts.Parameters.Set("page[limit]", strconv.Itoa(10))
|
|
||||||
offset := 0
|
|
||||||
OUTER:
|
OUTER:
|
||||||
for {
|
for {
|
||||||
opts.Parameters.Set("page[offset]", strconv.Itoa(offset))
|
|
||||||
|
|
||||||
var result api.ItemList
|
var result api.ItemList
|
||||||
var resp *http.Response
|
var resp *http.Response
|
||||||
err = f.pacer.Call(func() (bool, error) {
|
err = f.pacer.Call(func() (bool, error) {
|
||||||
@ -495,7 +495,15 @@ OUTER:
|
|||||||
break OUTER
|
break OUTER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
offset += 10
|
if !result.Links.Cursor.HasNext {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// Fetch the next from the URL in the response
|
||||||
|
nextURL, err := url.Parse(result.Links.Cursor.Next)
|
||||||
|
if err != nil {
|
||||||
|
return found, fmt.Errorf("failed to parse next link as URL: %w", err)
|
||||||
|
}
|
||||||
|
opts.Parameters.Set("page[next]", nextURL.Query().Get("page[next]"))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user