Update pg engine to preserve pre-existing indices if indexer receives 0 documents

Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
Eric Peterson
2022-11-29 15:13:31 +01:00
parent 18646ccb1a
commit b24cf5a99e
2 changed files with 23 additions and 0 deletions
@@ -81,6 +81,15 @@ describe('PgSearchEngineIndexer', () => {
expect(database.completeInsert).toHaveBeenCalledWith(tx, 'my-type');
});
it('should rollback transaction if no documents indexed', async () => {
await TestPipeline.fromIndexer(indexer).withDocuments([]).execute();
expect(database.getTransaction).toHaveBeenCalledTimes(1);
expect(database.insertDocuments).not.toHaveBeenCalled();
expect(database.completeInsert).not.toHaveBeenCalled();
expect(tx.rollback).toHaveBeenCalled();
});
it('should close out stream and bubble up error on prepare', async () => {
const expectedError = new Error('Prepare error');
const documents = [
@@ -35,6 +35,7 @@ export class PgSearchEngineIndexer extends BatchSearchEngineIndexer {
private store: DatabaseStore;
private type: string;
private tx: Knex.Transaction | undefined;
private numRecords = 0;
constructor(options: PgSearchEngineIndexerOptions) {
super({ batchSize: options.batchSize });
@@ -56,6 +57,8 @@ export class PgSearchEngineIndexer extends BatchSearchEngineIndexer {
}
async index(documents: IndexableDocument[]): Promise<void> {
this.numRecords += documents.length;
try {
await this.store.insertDocuments(this.tx!, this.type, documents);
} catch (e) {
@@ -67,6 +70,17 @@ export class PgSearchEngineIndexer extends BatchSearchEngineIndexer {
}
async finalize(): Promise<void> {
// If no documents were indexed, rollback the transaction, log a warning,
// and do not continue. This ensures that collators that return empty sets
// of documents do not cause the index to be deleted.
if (this.numRecords === 0) {
this.logger.warn(
`Index for ${this.type} was not replaced: indexer received 0 documents`,
);
this.tx!.rollback!();
return;
}
// Attempt to complete and commit the transaction.
try {
await this.store.completeInsert(this.tx!, this.type);