[PIT finder] return empty generator if first page is empty (#171598)

## Summary

Makes the PIT finder more consistent by ignoring empty first page and
not yielding it (as this is also what is done for other pages)

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Pierre Gayvallet 2023-11-27 16:12:52 +01:00 committed by GitHub
parent d900f8473b
commit 414260d42f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 81 additions and 1 deletions

View file

@ -235,6 +235,81 @@ describe('createPointInTimeFinder()', () => {
);
});
test('does not yield empty first page', async () => {
repository.openPointInTimeForType.mockResolvedValueOnce({
id: 'abc123',
});
repository.find.mockResolvedValueOnce({
total: 2,
saved_objects: [],
pit_id: 'abc123',
per_page: 2,
page: 0,
});
const findOptions: SavedObjectsCreatePointInTimeFinderOptions = {
type: ['visualization'],
search: 'foo*',
};
const internalOptions = {};
const finder = new PointInTimeFinder(findOptions, {
logger,
client: repository,
internalOptions,
});
const hits: SavedObjectsFindResult[] = [];
let pageCount = 0;
for await (const result of finder.find()) {
hits.push(...result.saved_objects);
pageCount++;
}
expect(pageCount).toEqual(0);
expect(hits.length).toEqual(0);
});
test('yields empty first page if aggregations are used', async () => {
repository.openPointInTimeForType.mockResolvedValueOnce({
id: 'abc123',
});
repository.find.mockResolvedValueOnce({
total: 2,
saved_objects: [],
pit_id: 'abc123',
per_page: 2,
page: 0,
});
const findOptions: SavedObjectsCreatePointInTimeFinderOptions = {
type: ['visualization'],
search: 'foo*',
aggs: {
some: {
avg: { field: 'fo' },
},
},
};
const internalOptions = {};
const finder = new PointInTimeFinder(findOptions, {
logger,
client: repository,
internalOptions,
});
const hits: SavedObjectsFindResult[] = [];
let pageCount = 0;
for await (const result of finder.find()) {
hits.push(...result.saved_objects);
pageCount++;
}
expect(pageCount).toEqual(1);
expect(hits.length).toEqual(0);
});
test('still applies the defaults in the mandatory fields even when `undefined` is explicitly provided', async () => {
repository.openPointInTimeForType.mockResolvedValueOnce({
id: 'abc123',

View file

@ -93,7 +93,12 @@ export class PointInTimeFinder<T = unknown, A = unknown>
await this.close();
}
yield results;
// do not yield first page if empty, unless there are aggregations
// (in which case we always want to return at least one page)
if (lastResultsCount > 0 || this.#findOptions.aggs) {
yield results;
}
// We've reached the end when there are fewer hits than our perPage size,
// or when `close()` has been called.
} while (this.#open && lastResultsCount >= this.#findOptions.perPage!);