Skip to content

Commit 749bab9

Browse files
committed
exporthistory: guard against repeated continuation tokens in pageable
1 parent 0b19f79 commit 749bab9

1 file changed

Lines changed: 12 additions & 4 deletions

File tree

exporthistory/src/main/java/com/microsoft/durabletask/exporthistory/client/ExportJobQueryPageable.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,22 @@ public ExportJobDescription next() {
5757
}
5858

5959
private void fetchNextPage() {
60+
String previousToken = this.continuationToken;
6061
ExportJobQuery query = new ExportJobQuery(
6162
baseQuery != null ? baseQuery.getStatus() : null,
6263
baseQuery != null ? baseQuery.getJobIdPrefix() : null,
6364
baseQuery != null ? baseQuery.getCreatedFrom() : null,
6465
baseQuery != null ? baseQuery.getCreatedTo() : null,
6566
baseQuery != null ? baseQuery.getPageSize() : null,
66-
this.continuationToken);
67+
previousToken);
6768

6869
ExportJobQueryResult result = queryExecutor.apply(query);
6970
this.currentPage = result.getJobs().iterator();
7071
this.continuationToken = result.getContinuationToken();
71-
this.hasMorePages = this.continuationToken != null && !this.continuationToken.isEmpty();
72+
boolean hasToken = this.continuationToken != null && !this.continuationToken.isEmpty();
73+
// Safety guard: if the backend echoes the same continuation token, treat the
74+
// stream as exhausted to avoid an infinite loop in hasNext()'s empty-page loop.
75+
this.hasMorePages = hasToken && !this.continuationToken.equals(previousToken);
7276
}
7377
};
7478
}
@@ -92,17 +96,21 @@ public ExportJobQueryResult next() {
9296
if (!hasNext()) {
9397
throw new java.util.NoSuchElementException();
9498
}
99+
String previousToken = this.continuationToken;
95100
ExportJobQuery query = new ExportJobQuery(
96101
baseQuery != null ? baseQuery.getStatus() : null,
97102
baseQuery != null ? baseQuery.getJobIdPrefix() : null,
98103
baseQuery != null ? baseQuery.getCreatedFrom() : null,
99104
baseQuery != null ? baseQuery.getCreatedTo() : null,
100105
baseQuery != null ? baseQuery.getPageSize() : null,
101-
this.continuationToken);
106+
previousToken);
102107

103108
ExportJobQueryResult result = queryExecutor.apply(query);
104109
this.continuationToken = result.getContinuationToken();
105-
this.hasMorePages = this.continuationToken != null && !this.continuationToken.isEmpty();
110+
boolean hasToken = this.continuationToken != null && !this.continuationToken.isEmpty();
111+
// Safety guard: if the backend echoes the same continuation token, treat the
112+
// stream as exhausted to avoid endless re-fetching of the same page.
113+
this.hasMorePages = hasToken && !this.continuationToken.equals(previousToken);
106114
return result;
107115
}
108116
};

0 commit comments

Comments
 (0)