From 6ff683a627b537a14031440b88b9bcc669629302 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Wed, 28 Jan 2026 12:30:33 -0800 Subject: [PATCH] s3tables: implement token-based pagination for table buckets listing --- .../s3tables/handler_bucket_get_list_delete.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/weed/s3api/s3tables/handler_bucket_get_list_delete.go b/weed/s3api/s3tables/handler_bucket_get_list_delete.go index 830bf9e6c..b1044cfd2 100644 --- a/weed/s3api/s3tables/handler_bucket_get_list_delete.go +++ b/weed/s3api/s3tables/handler_bucket_get_list_delete.go @@ -90,14 +90,14 @@ func (h *S3TablesHandler) handleListTableBuckets(w http.ResponseWriter, r *http. var buckets []TableBucketSummary - var lastFileName string + lastFileName := req.ContinuationToken err := filerClient.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error { for len(buckets) < maxBuckets { resp, err := client.ListEntries(r.Context(), &filer_pb.ListEntriesRequest{ Directory: TablesPath, Limit: uint32(maxBuckets * 2), // Fetch more than needed to account for filtering StartFromFileName: lastFileName, - InclusiveStartFrom: lastFileName == "", + InclusiveStartFrom: lastFileName == "" || lastFileName == req.ContinuationToken, }) if err != nil { return err @@ -115,6 +115,12 @@ func (h *S3TablesHandler) handleListTableBuckets(w http.ResponseWriter, r *http. if entry.Entry == nil { continue } + + // Skip the start item if it was included in the previous page + if len(buckets) == 0 && req.ContinuationToken != "" && entry.Entry.Name == req.ContinuationToken { + continue + } + hasMore = true lastFileName = entry.Entry.Name @@ -173,8 +179,14 @@ func (h *S3TablesHandler) handleListTableBuckets(w http.ResponseWriter, r *http. } } + paginationToken := "" + if len(buckets) >= maxBuckets { + paginationToken = lastFileName + } + resp := &ListTableBucketsResponse{ - TableBuckets: buckets, + TableBuckets: buckets, + ContinuationToken: paginationToken, } h.writeJSON(w, http.StatusOK, resp)