@speckle/objectloader2
Version:
This is an updated objectloader for the Speckle viewer written in typescript
79 lines • 2.73 kB
JavaScript
import { TIME } from '@speckle/shared';
import BatchingQueue from './batchingQueue.js';
export class CachePump {
#writeQueue;
#database;
#logger;
#deferments;
#gathered;
#options;
#disposed = false;
constructor(database, gathered, deferments, options) {
this.#database = database;
this.#gathered = gathered;
this.#deferments = deferments;
this.#options = options;
this.#logger = options.logger || (() => { });
}
add(item) {
if (!this.#writeQueue) {
this.#writeQueue = new BatchingQueue({
batchSize: this.#options.maxCacheWriteSize,
maxWaitTime: this.#options.maxCacheBatchWriteWait,
processFunction: (batch) => this.#database.cacheSaveBatch({ batch })
});
}
this.#writeQueue.add(item.baseId, item);
}
async disposeAsync() {
await this.#writeQueue?.disposeAsync();
await this.#database.disposeAsync();
this.#disposed = true;
}
get isDisposed() {
return this.#disposed;
}
async pumpItems(params) {
const { ids, foundItems, notFoundItems } = params;
const maxCacheReadSize = this.#options.maxCacheReadSize;
for (let i = 0; i < ids.length;) {
if (this.isDisposed)
break;
if ((this.#writeQueue?.count() ?? 0) > this.#options.maxWriteQueueSize) {
this.#logger('pausing reads (# in write queue: ' + this.#writeQueue?.count() + ')');
await new Promise((resolve) => setTimeout(resolve, TIME.second)); // Pause for 1 second, protects against out of memory
continue;
}
const batch = ids.slice(i, i + maxCacheReadSize);
const cachedData = await this.#database.getAll(batch);
for (let i = 0; i < cachedData.length; i++) {
if (cachedData[i]) {
foundItems.add(cachedData[i]);
}
else {
notFoundItems.add(batch[i]);
}
}
i += maxCacheReadSize;
}
}
async *gather(ids, downloader) {
const total = ids.length;
const pumpPromise = this.pumpItems({
ids,
foundItems: this.#gathered,
notFoundItems: downloader
});
let count = 0;
for await (const item of this.#gathered.consume()) {
this.#deferments.undefer(item);
yield item;
count++;
if (count >= total) {
this.#gathered.dispose();
}
}
await pumpPromise;
}
}
//# sourceMappingURL=cachePump.js.map