♻️ cli: buffering reindexing of documents
This commit is contained in:
committed by
ericlinagora
parent
3e2adf9c1c
commit
5766d2684b
@@ -13,6 +13,7 @@ import iterateOverRepoPages from "../../../utils/iterate-over-repository-pages";
|
|||||||
|
|
||||||
import BaseReindexer from "./base-reindexer";
|
import BaseReindexer from "./base-reindexer";
|
||||||
import type ReindexerOptions from "./reindexer-options";
|
import type ReindexerOptions from "./reindexer-options";
|
||||||
|
import BufferedAction from "../../../utils/buffered-action";
|
||||||
|
|
||||||
export default class DocumentsReindexer extends BaseReindexer<DriveFile> {
|
export default class DocumentsReindexer extends BaseReindexer<DriveFile> {
|
||||||
constructor(platform: TdrivePlatform, options: ReindexerOptions) {
|
constructor(platform: TdrivePlatform, options: ReindexerOptions) {
|
||||||
@@ -62,6 +63,7 @@ export default class DocumentsReindexer extends BaseReindexer<DriveFile> {
|
|||||||
const repository = await this.dbRepository();
|
const repository = await this.dbRepository();
|
||||||
let count = 0,
|
let count = 0,
|
||||||
countChanged = 0;
|
countChanged = 0;
|
||||||
|
const bufferedWriter = new BufferedAction<DriveFile>(100, items => repository.saveAll(items));
|
||||||
await iterateOverRepoPages(
|
await iterateOverRepoPages(
|
||||||
repository,
|
repository,
|
||||||
async entities => {
|
async entities => {
|
||||||
@@ -99,12 +101,13 @@ export default class DocumentsReindexer extends BaseReindexer<DriveFile> {
|
|||||||
);
|
);
|
||||||
if (content_keywords !== entity.content_keywords) {
|
if (content_keywords !== entity.content_keywords) {
|
||||||
entity.content_keywords = content_keywords;
|
entity.content_keywords = content_keywords;
|
||||||
repository.save(entity);
|
bufferedWriter.do(entity);
|
||||||
countChanged++;
|
countChanged++;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.statusFail(err.stack);
|
this.statusFail(err.stack);
|
||||||
}
|
}
|
||||||
|
bufferedWriter.flush();
|
||||||
}
|
}
|
||||||
this.statusStart(`Repaired ${count} documents (${countChanged} changed)`);
|
this.statusStart(`Repaired ${count} documents (${countChanged} changed)`);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/** Batch operations on objects into groups of `minimumBatchSize`
|
||||||
|
* provided to the constructor's callback.
|
||||||
|
*
|
||||||
|
* Call `do` or `doAll` to enqueue items, don't forget to:
|
||||||
|
* - call flush after all items are enqueued
|
||||||
|
* - await all the methods (do* and flush)
|
||||||
|
*
|
||||||
|
* The callback can be called with more than `minimumBatchSize`
|
||||||
|
* when `doAll` is used - see note on that method.
|
||||||
|
*/
|
||||||
|
export default class BufferedAction<T> {
|
||||||
|
// TODO: low and high marks
|
||||||
|
private buffer: T[] = [];
|
||||||
|
constructor(
|
||||||
|
private readonly minimumBatchSize: number,
|
||||||
|
private readonly action: (items: T[]) => Promise<void>,
|
||||||
|
) {}
|
||||||
|
/** Call to empty all items by calling the callback with all items if at least one is queued */
|
||||||
|
public async flush() {
|
||||||
|
const buffer = this.buffer;
|
||||||
|
if (!buffer.length) return 0;
|
||||||
|
this.buffer = new Array(this.minimumBatchSize);
|
||||||
|
this.action(buffer);
|
||||||
|
return buffer.length;
|
||||||
|
}
|
||||||
|
private async flushIfShould() {
|
||||||
|
return this.buffer.length >= this.minimumBatchSize ? await this.flush() : 0;
|
||||||
|
}
|
||||||
|
/** Enqueue a single item to process in the batch later. Returns items actually processed. */
|
||||||
|
public async do(item: T) {
|
||||||
|
this.buffer.push(item);
|
||||||
|
return await this.flushIfShould();
|
||||||
|
}
|
||||||
|
/** Enqueue an array of items to process in the batch later.
|
||||||
|
* If the additional items goes beyond `minimumBatchSize`,
|
||||||
|
* all items will be flushed at once, however many was added
|
||||||
|
* by `doAll`.
|
||||||
|
* Returns items actually processed. */
|
||||||
|
public async doAll(items: T[]) {
|
||||||
|
this.buffer = this.buffer.concat(items);
|
||||||
|
return await this.flushIfShould();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user