Use Q promises and isPending to make logic simpler
This commit is contained in:
parent
f3df86872b
commit
6f3b70dbb0
|
@ -16,6 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
import PlatformPeg from 'matrix-react-sdk/lib/PlatformPeg';
|
import PlatformPeg from 'matrix-react-sdk/lib/PlatformPeg';
|
||||||
import request from "browser-request";
|
import request from "browser-request";
|
||||||
|
import q from "q";
|
||||||
|
|
||||||
// This module contains all the code needed to log the console, persist it to
|
// This module contains all the code needed to log the console, persist it to
|
||||||
// disk and submit bug reports. Rationale is as follows:
|
// disk and submit bug reports. Rationale is as follows:
|
||||||
|
@ -105,9 +106,6 @@ class IndexedDBLogStore {
|
||||||
this.db = null;
|
this.db = null;
|
||||||
// Promise is not null when a flush is IN PROGRESS
|
// Promise is not null when a flush is IN PROGRESS
|
||||||
this.flushPromise = null;
|
this.flushPromise = null;
|
||||||
// Promise is not null when flush() is called when one is already in
|
|
||||||
// progress.
|
|
||||||
this.flushAgainPromise = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,7 +113,7 @@ class IndexedDBLogStore {
|
||||||
*/
|
*/
|
||||||
connect() {
|
connect() {
|
||||||
let req = this.indexedDB.open("logs");
|
let req = this.indexedDB.open("logs");
|
||||||
return new Promise((resolve, reject) => {
|
return q.Promise((resolve, reject) => {
|
||||||
req.onsuccess = (event) => {
|
req.onsuccess = (event) => {
|
||||||
this.db = event.target.result;
|
this.db = event.target.result;
|
||||||
// Periodically flush logs to local storage / indexeddb
|
// Periodically flush logs to local storage / indexeddb
|
||||||
|
@ -167,13 +165,10 @@ class IndexedDBLogStore {
|
||||||
* - If B doesn't wait for A's flush to complete, B will be missing the
|
* - If B doesn't wait for A's flush to complete, B will be missing the
|
||||||
* contents of A's flush.
|
* contents of A's flush.
|
||||||
* To protect against this, we set 'flushPromise' when a flush is ongoing.
|
* To protect against this, we set 'flushPromise' when a flush is ongoing.
|
||||||
* Subsequent calls to flush() during this period return a new promise
|
* Subsequent calls to flush() during this period will chain another flush.
|
||||||
* 'flushAgainPromise' which is chained off the current 'flushPromise'.
|
* This guarantees that we WILL do a brand new flush at some point in the
|
||||||
* Subsequent calls to flush() when the first flush hasn't completed will
|
* future. Once the flushes have finished, it's safe to clobber the promise
|
||||||
* return the same 'flushAgainPromise' as we can guarantee that we WILL
|
* with a new one to prevent very deep promise chains from building up.
|
||||||
* do a brand new flush at some point in the future. Once the first flush
|
|
||||||
* has completed, 'flushAgainPromise' becomes 'flushPromise' and can be
|
|
||||||
* chained again.
|
|
||||||
*
|
*
|
||||||
* This guarantees that we will always eventually do a flush when flush() is
|
* This guarantees that we will always eventually do a flush when flush() is
|
||||||
* called.
|
* called.
|
||||||
|
@ -181,23 +176,20 @@ class IndexedDBLogStore {
|
||||||
* @return {Promise} Resolved when the logs have been flushed.
|
* @return {Promise} Resolved when the logs have been flushed.
|
||||||
*/
|
*/
|
||||||
flush() {
|
flush() {
|
||||||
if (this.flushPromise) { // a flush is ongoing
|
// check if a flush() operation is ongoing
|
||||||
if (this.flushAgainPromise) { // a flush is queued up, return that.
|
if (this.flushPromise && this.flushPromise.isPending()) {
|
||||||
return this.flushAgainPromise;
|
// chain a flush operation after this one has completed to guarantee
|
||||||
}
|
// that a complete flush() is done. This does mean that if there are
|
||||||
// queue up a new flush
|
// 3 calls to flush() in one go, the 2nd and 3rd promises will run
|
||||||
this.flushAgainPromise = this.flushPromise.then(() => {
|
// concurrently, but this is fine since they can safely race when
|
||||||
// the current flush has completed, so shuffle the promises
|
// collecting logs.
|
||||||
// around:
|
return this.flushPromise.then(() => {
|
||||||
// flushAgainPromise => flushPromise and null flushAgainPromise.
|
|
||||||
// flushPromise has already nulled itself.
|
|
||||||
this.flushAgainPromise = null;
|
|
||||||
return this.flush();
|
return this.flush();
|
||||||
});
|
});
|
||||||
return this.flushAgainPromise;
|
|
||||||
}
|
}
|
||||||
|
// there is no flush promise or there was but it has finished, so do
|
||||||
this.flushPromise = new Promise((resolve, reject) => {
|
// a brand new one, destroying the chain which may have been built up.
|
||||||
|
this.flushPromise = q.Promise((resolve, reject) => {
|
||||||
if (!this.db) {
|
if (!this.db) {
|
||||||
// not connected yet or user rejected access for us to r/w to
|
// not connected yet or user rejected access for us to r/w to
|
||||||
// the db.
|
// the db.
|
||||||
|
@ -225,10 +217,6 @@ class IndexedDBLogStore {
|
||||||
new Error("Failed to write logs: " + event.target.errorCode)
|
new Error("Failed to write logs: " + event.target.errorCode)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}).then(() => {
|
|
||||||
this.flushPromise = null;
|
|
||||||
}, (err) => {
|
|
||||||
this.flushPromise = null;
|
|
||||||
});
|
});
|
||||||
return this.flushPromise;
|
return this.flushPromise;
|
||||||
}
|
}
|
||||||
|
@ -286,7 +274,7 @@ class IndexedDBLogStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteLogs(id) {
|
function deleteLogs(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return q.Promise((resolve, reject) => {
|
||||||
const txn = db.transaction(
|
const txn = db.transaction(
|
||||||
["logs", "logslastmod"], "readwrite"
|
["logs", "logslastmod"], "readwrite"
|
||||||
);
|
);
|
||||||
|
@ -377,7 +365,7 @@ class IndexedDBLogStore {
|
||||||
*/
|
*/
|
||||||
function selectQuery(store, keyRange, resultMapper) {
|
function selectQuery(store, keyRange, resultMapper) {
|
||||||
const query = store.openCursor(keyRange);
|
const query = store.openCursor(keyRange);
|
||||||
return new Promise((resolve, reject) => {
|
return q.Promise((resolve, reject) => {
|
||||||
let results = [];
|
let results = [];
|
||||||
query.onerror = (event) => {
|
query.onerror = (event) => {
|
||||||
reject(new Error("Query failed: " + event.target.errorCode));
|
reject(new Error("Query failed: " + event.target.errorCode));
|
||||||
|
@ -479,7 +467,7 @@ module.exports = {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await q.Promise((resolve, reject) => {
|
||||||
request({
|
request({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: bugReportEndpoint,
|
url: bugReportEndpoint,
|
||||||
|
|
Loading…
Reference in New Issue