Merge pull request #2195 from matrix-org/dbkr/indexeddb_fallback

Fall back to another store if indexeddb start fails
pull/21833/head
Bruno Windels 2018-10-08 15:37:59 +02:00 committed by GitHub
commit 86da88052a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 16 deletions

View File

@ -18,6 +18,8 @@ limitations under the License.
'use strict'; 'use strict';
import Matrix from 'matrix-js-sdk';
import utils from 'matrix-js-sdk/lib/utils'; import utils from 'matrix-js-sdk/lib/utils';
import EventTimeline from 'matrix-js-sdk/lib/models/event-timeline'; import EventTimeline from 'matrix-js-sdk/lib/models/event-timeline';
import EventTimelineSet from 'matrix-js-sdk/lib/models/event-timeline-set'; import EventTimelineSet from 'matrix-js-sdk/lib/models/event-timeline-set';
@ -51,6 +53,9 @@ class MatrixClientPeg {
this.opts = { this.opts = {
initialSyncLimit: 20, initialSyncLimit: 20,
}; };
// the credentials used to init the current client object.
// used if we tear it down & recreate it with a different store
this._currentClientCreds = null;
} }
/** /**
@ -79,10 +84,30 @@ class MatrixClientPeg {
* Home Server / Identity Server URLs and active credentials * Home Server / Identity Server URLs and active credentials
*/ */
replaceUsingCreds(creds: MatrixClientCreds) { replaceUsingCreds(creds: MatrixClientCreds) {
this._currentClientCreds = creds;
this._createClient(creds); this._createClient(creds);
} }
async start() { async start() {
for (const dbType of ['indexeddb', 'memory']) {
try {
const promise = this.matrixClient.store.startup();
console.log("MatrixClientPeg: waiting for MatrixClient store to initialise");
await promise;
break;
} catch (err) {
if (dbType === 'indexeddb') {
console.error('Error starting matrixclient store - falling back to memory store', err);
this.matrixClient.store = new Matrix.MatrixInMemoryStore({
localStorage: global.localStorage,
});
} else {
console.error('Failed to start memory store!', err);
throw err;
}
}
}
// try to initialise e2e on the new client // try to initialise e2e on the new client
try { try {
// check that we have a version of the js-sdk which includes initCrypto // check that we have a version of the js-sdk which includes initCrypto
@ -103,18 +128,6 @@ class MatrixClientPeg {
opts.lazyLoadMembers = true; opts.lazyLoadMembers = true;
} }
try {
const promise = this.matrixClient.store.startup();
console.log(`MatrixClientPeg: waiting for MatrixClient store to initialise`);
await promise;
} catch (err) {
// log any errors when starting up the database (if one exists)
console.error('Error starting matrixclient store', err);
}
// regardless of errors, start the client. If we did error out, we'll
// just end up doing a full initial /sync.
// Connect the matrix client to the dispatcher // Connect the matrix client to the dispatcher
MatrixActionCreators.start(this.matrixClient); MatrixActionCreators.start(this.matrixClient);
@ -147,7 +160,7 @@ class MatrixClientPeg {
return matches[1]; return matches[1];
} }
_createClient(creds: MatrixClientCreds) { _createClient(creds: MatrixClientCreds, useIndexedDb) {
const opts = { const opts = {
baseUrl: creds.homeserverUrl, baseUrl: creds.homeserverUrl,
idBaseUrl: creds.identityServerUrl, idBaseUrl: creds.identityServerUrl,
@ -158,7 +171,7 @@ class MatrixClientPeg {
forceTURN: SettingsStore.getValue('webRtcForceTURN', false), forceTURN: SettingsStore.getValue('webRtcForceTURN', false),
}; };
this.matrixClient = createMatrixClient(opts, this.indexedDbWorkerScript); this.matrixClient = createMatrixClient(opts, useIndexedDb);
// we're going to add eventlisteners for each matrix event tile, so the // we're going to add eventlisteners for each matrix event tile, so the
// potential number of event listeners is quite high. // potential number of event listeners is quite high.

View File

@ -32,13 +32,18 @@ try {
* @param {Object} opts options to pass to Matrix.createClient. This will be * @param {Object} opts options to pass to Matrix.createClient. This will be
* extended with `sessionStore` and `store` members. * extended with `sessionStore` and `store` members.
* *
* @param {bool} useIndexedDb True to attempt to use indexeddb, or false to force
* use of the memory store. Default: true.
*
* @property {string} indexedDbWorkerScript Optional URL for a web worker script * @property {string} indexedDbWorkerScript Optional URL for a web worker script
* for IndexedDB store operations. By default, indexeddb ops are done on * for IndexedDB store operations. By default, indexeddb ops are done on
* the main thread. * the main thread.
* *
* @returns {MatrixClient} the newly-created MatrixClient * @returns {MatrixClient} the newly-created MatrixClient
*/ */
export default function createMatrixClient(opts) { export default function createMatrixClient(opts, useIndexedDb) {
if (useIndexedDb === undefined) useIndexedDb = true;
const storeOpts = { const storeOpts = {
useAuthorizationHeader: true, useAuthorizationHeader: true,
}; };
@ -47,7 +52,7 @@ export default function createMatrixClient(opts) {
storeOpts.sessionStore = new Matrix.WebStorageSessionStore(localStorage); storeOpts.sessionStore = new Matrix.WebStorageSessionStore(localStorage);
} }
if (indexedDB && localStorage) { if (indexedDB && localStorage && useIndexedDb) {
storeOpts.store = new Matrix.IndexedDBStore({ storeOpts.store = new Matrix.IndexedDBStore({
indexedDB: indexedDB, indexedDB: indexedDB,
dbName: "riot-web-sync", dbName: "riot-web-sync",