diff --git a/src/plugins/persistence/couch/CouchObjectProvider.js b/src/plugins/persistence/couch/CouchObjectProvider.js index e6c04b4538..024c5e154f 100644 --- a/src/plugins/persistence/couch/CouchObjectProvider.js +++ b/src/plugins/persistence/couch/CouchObjectProvider.js @@ -24,6 +24,7 @@ import CouchDocument from "./CouchDocument"; import CouchObjectQueue from "./CouchObjectQueue"; import { PENDING, CONNECTED, DISCONNECTED, UNKNOWN } from "./CouchStatusIndicator"; import { isNotebookOrAnnotationType } from '../../notebook/notebook-constants.js'; +import _ from 'lodash'; const REV = "_rev"; const ID = "_id"; @@ -42,6 +43,8 @@ class CouchObjectProvider { this.batchIds = []; this.onEventMessage = this.onEventMessage.bind(this); this.onEventError = this.onEventError.bind(this); + this.flushPersistenceQueue = _.debounce(this.flushPersistenceQueue.bind(this)); + this.persistenceQueue = []; } /** @@ -666,7 +669,11 @@ class CouchObjectProvider { const queued = this.objectQueue[key].dequeue(); let document = new CouchDocument(key, queued.model); document.metadata.created = Date.now(); - this.request(key, "PUT", document).then((response) => { + + this.put({ + key, + document + }).then((response) => { this.#checkResponse(response, queued.intermediateResponse, key); }).catch(error => { queued.intermediateResponse.reject(error); @@ -677,6 +684,50 @@ class CouchObjectProvider { return intermediateResponse.promise; } + put({key, document}) { + return new Promise((resolve, reject) => { + this.persistenceQueue.push({ + key, + document, + resolve, + reject + }); + this.flushPersistenceQueue(); + }); + + } + + async flushPersistenceQueue() { + if (this.persistenceQueue.length > 1) { + const batch = { + docs: this.persistenceQueue.map((queued) => queued.document) + }; + const response = await this.request("_bulk_docs", "POST", batch); + response.forEach((responseMetadatum) => { + const queued = this.persistenceQueue.find((queuedMetadatum) => queuedMetadatum.key === responseMetadatum.id); + if (responseMetadatum.ok) { + queued.resolve(responseMetadatum); + } else { + queued.reject(responseMetadatum); + } + }); + } else if (this.persistenceQueue.length === 1) { + const { + key, + document, + resolve, + reject + } = this.persistenceQueue[0]; + + this.request(key, "PUT", document) + .then(resolve) + .catch(reject); + + } + + this.persistenceQueue = []; + } + /** * @private */