From 076c1425a8d0a03177191b8afe97067e681ee271 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Thu, 8 Jun 2023 16:45:00 +0200 Subject: [PATCH] batching, but query is messed up --- index.html | 3 +- .../persistence/couch/CouchSearchProvider.js | 79 ++++++++++++++++--- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/index.html b/index.html index e8d460c35b..986027e2c1 100644 --- a/index.html +++ b/index.html @@ -103,7 +103,8 @@ const TWO_HOURS = ONE_HOUR * 2; const ONE_DAY = ONE_HOUR * 24; - openmct.install(openmct.plugins.LocalStorage()); + //openmct.install(openmct.plugins.LocalStorage()); + openmct.install(openmct.plugins.CouchDB("http://localhost:5984/openmct")); openmct.install(openmct.plugins.example.Generator()); openmct.install(openmct.plugins.example.EventGeneratorPlugin()); diff --git a/src/plugins/persistence/couch/CouchSearchProvider.js b/src/plugins/persistence/couch/CouchSearchProvider.js index aa7efa74d8..b1fef2d129 100644 --- a/src/plugins/persistence/couch/CouchSearchProvider.js +++ b/src/plugins/persistence/couch/CouchSearchProvider.js @@ -27,7 +27,13 @@ // If the above namespace is ever resolved, we can fold this search provider // back into the object provider. +const BATCH_ANNOTATION_DEBOUNCE_MS = 500; + class CouchSearchProvider { + #bulkPromise; + #batchIds; + #lastAbortSignal; + constructor(couchObjectProvider) { this.couchObjectProvider = couchObjectProvider; this.searchTypes = couchObjectProvider.openmct.objects.SEARCH_TYPES; @@ -36,6 +42,8 @@ class CouchSearchProvider { this.searchTypes.ANNOTATIONS, this.searchTypes.TAGS ]; + this.#batchIds = []; + this.#bulkPromise = null; } supportsSearchType(searchType) { @@ -68,28 +76,79 @@ class CouchSearchProvider { return this.couchObjectProvider.getObjectsByFilter(filter, abortSignal); } - searchForAnnotations(keyString, abortSignal) { + async #deferBatchAnnotationSearch() { + // We until the next event loop cycle to "collect" all of the get + // requests triggered in this iteration of the event loop + await this.#waitForDebounce(); + const batchIdsToSearch = [...this.#batchIds]; + this.#clearBatch(); + return this.#bulkAnnotationSearch(batchIdsToSearch); + } + + #clearBatch() { + this.#batchIds = []; + this.#bulkPromise = undefined; + } + + #waitForDebounce() { + let timeoutID; + clearTimeout(timeoutID); + + return new Promise((resolve) => { + timeoutID = setTimeout(() => { + resolve(); + }, BATCH_ANNOTATION_DEBOUNCE_MS); + }); + } + + #bulkAnnotationSearch(batchIdsToSearch) { const filter = { selector: { $and: [ - { - model: { - targets: {} - } - }, { 'model.type': { $eq: 'annotation' } + }, + { + $or: [] } ] } }; - filter.selector.$and[0].model.targets[keyString] = { - $exists: true - }; + let lastAbortSignal = null; + // TODO: should remove duplicates from batchIds + batchIdsToSearch.forEach(({ keyString, abortSignal }) => { + const modelFilter = { + model: { + targets: {} + } + }; + modelFilter.model.targets[keyString] = { + $exists: true + }; - return this.couchObjectProvider.getObjectsByFilter(filter, abortSignal); + filter.selector.$and[1].$or.push(modelFilter); + lastAbortSignal = abortSignal; + }); + + return this.couchObjectProvider.getObjectsByFilter(filter, lastAbortSignal); + } + + async searchForAnnotations(keyString, abortSignal) { + this.#batchIds.push({ keyString, abortSignal }); + console.debug(`🔍 Searching for annotations with key: ${keyString}`); + if (!this.#bulkPromise) { + this.#bulkPromise = this.#deferBatchAnnotationSearch(); + } + + try { + const returnedData = await this.#bulkPromise; + // TODO: find the latest annotation for given key + return returnedData; + } catch (error) { + console.error(error); + } } searchForTags(tagsArray, abortSignal) {