1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-29 16:43:09 +03:00

Merge branch 'dbkr/indexeddb_webworker' into dbkr/indexeddb_webworker_dont_transfer_sync

This commit is contained in:
David Baker
2017-04-07 15:01:42 +01:00
7 changed files with 69 additions and 18 deletions

View File

@@ -13,9 +13,14 @@ const MatrixEvent = sdk.MatrixEvent;
*/ */
module.exports.syncPromise = function(client) { module.exports.syncPromise = function(client) {
const def = q.defer(); const def = q.defer();
client.on('sync', (state) => { const cb = (state) => {
if (state == 'SYNCING') def.resolve(); if (state == 'SYNCING') {
}); def.resolve();
} else {
client.once('sync', cb);
}
};
client.once('sync', cb);
return def.promise; return def.promise;
}; };

24
src/indexeddb-worker.js Normal file
View File

@@ -0,0 +1,24 @@
/*
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* Separate exports file for the indexeddb web worker, which is designed
* to be used separately
*/
/** The {@link module:indexeddb-store-worker~IndexedDBStoreWorker} class. */
module.exports.IndexedDBStoreWorker = require("./store/indexeddb-store-worker.js");

View File

@@ -61,8 +61,6 @@ module.exports.Filter = require("./filter");
module.exports.TimelineWindow = require("./timeline-window").TimelineWindow; module.exports.TimelineWindow = require("./timeline-window").TimelineWindow;
/** The {@link module:interactive-auth} class. */ /** The {@link module:interactive-auth} class. */
module.exports.InteractiveAuth = require("./interactive-auth"); module.exports.InteractiveAuth = require("./interactive-auth");
/** The {@link module:indexeddb-remote-worker} class. */
module.exports.IndexedDbStoreWorker = require("./store/indexeddb-remote-worker.js");
/** /**

View File

@@ -243,7 +243,7 @@ LocalIndexedDBStoreBackend.prototype = {
/** /**
* Persist a list of [user id, presence event] they are for. * Persist a list of [user id, presence event] they are for.
* Users with the same 'userId' will be replaced. * Users with the same 'userId' will be replaced.
* Prfesence events should be the event in its raw form (not the Event * Presence events should be the event in its raw form (not the Event
* object) * object)
* @param {Object[]} tuples An array of [userid, event] tuples * @param {Object[]} tuples An array of [userid, event] tuples
* @return {Promise} Resolves if the users were persisted. * @return {Promise} Resolves if the users were persisted.

View File

@@ -30,6 +30,7 @@ import q from "q";
const RemoteIndexedDBStoreBackend = function RemoteIndexedDBStoreBackend( const RemoteIndexedDBStoreBackend = function RemoteIndexedDBStoreBackend(
workerScript, dbName, workerScript, dbName,
) { ) {
this._dbName = dbName;
this._worker = new Worker(workerScript); this._worker = new Worker(workerScript);
this._nextSeq = 0; this._nextSeq = 0;
// The currently in-flight requests to the actual backend // The currently in-flight requests to the actual backend
@@ -38,10 +39,6 @@ const RemoteIndexedDBStoreBackend = function RemoteIndexedDBStoreBackend(
}; };
this._worker.onmessage = this._onWorkerMessage.bind(this); this._worker.onmessage = this._onWorkerMessage.bind(this);
this._doCmd('_setupWorker', [dbName]).done(() => {
console.log("IndexedDB worker is ready");
});
}; };
@@ -52,7 +49,10 @@ RemoteIndexedDBStoreBackend.prototype = {
* @return {Promise} Resolves if successfully connected. * @return {Promise} Resolves if successfully connected.
*/ */
connect: function() { connect: function() {
return this._doCmd('_setupWorker', [this._dbName]).then(() => {
console.log("IndexedDB worker is ready");
return this._doCmd('connect'); return this._doCmd('connect');
});
}, },
/** /**

View File

@@ -18,10 +18,25 @@ import q from "q";
import LocalIndexedDBStoreBackend from "./indexeddb-local-backend.js"; import LocalIndexedDBStoreBackend from "./indexeddb-local-backend.js";
/** /**
* This class lives in the webworker and drives a LocalIndexedDbStoreBackend * This class lives in the webworker and drives a LocalIndexedDBStoreBackend
* controlled by messages from the main process. * controlled by messages from the main process.
*
* It should be instantiated by a web worker script provided by the application
* in a script, for example:
*
* import {IndexedDBStoreWorker} from 'matrix-js-sdk/lib/indexeddb-worker.js';
* const remoteWorker = new IndexedDBStoreWorker(postMessage);
* onmessage = remoteWorker.onMessage;
*
* Note that it is advisable to import this class by referencing the file directly to
* avoid a dependency on the whole js-sdk.
*
*/
class IndexedDBStoreWorker {
/**
* @param {function} postMessage The web worker postMessage function that
* should be used to communicate back to the main script.
*/ */
class IndexedDbStoreWorker {
constructor(postMessage) { constructor(postMessage) {
this.backend = null; this.backend = null;
this.postMessage = postMessage; this.postMessage = postMessage;
@@ -29,6 +44,12 @@ class IndexedDbStoreWorker {
this.onMessage = this.onMessage.bind(this); this.onMessage = this.onMessage.bind(this);
} }
/**
* Passes a message event from the main script into the class. This method
* can be directly assigned to the web worker `onmessage` variable.
*
* @param {Object} ev The message event
*/
onMessage(ev) { onMessage(ev) {
const msg = ev.data; const msg = ev.data;
let prom; let prom;
@@ -51,7 +72,7 @@ class IndexedDbStoreWorker {
case 'clearDatabase': case 'clearDatabase':
prom = this.backend.clearDatabase().then((result) => { prom = this.backend.clearDatabase().then((result) => {
// This returns special classes which can't be cloned // This returns special classes which can't be cloned
// accross to the main script, so don't try. // across to the main script, so don't try.
return {}; return {};
}); });
break; break;
@@ -76,7 +97,7 @@ class IndexedDbStoreWorker {
postMessage({ postMessage({
command: 'cmd_fail', command: 'cmd_fail',
seq: msg.seq, seq: msg.seq,
// Canb't be an Error because they're not structured cloneable // Can't be an Error because they're not structured cloneable
error: "Unrecognised command", error: "Unrecognised command",
}); });
return; return;
@@ -89,13 +110,16 @@ class IndexedDbStoreWorker {
result: ret, result: ret,
}); });
}, (err) => { }, (err) => {
console.error("Error running command: "+msg.command);
console.error(err);
this.postMessage.call(null, { this.postMessage.call(null, {
command: 'cmd_fail', command: 'cmd_fail',
seq: msg.seq, seq: msg.seq,
error: err, // Just send a string because Error objects aren't cloneable
error: "Error running command",
}); });
}); });
} }
} }
module.exports = IndexedDbStoreWorker; module.exports = IndexedDBStoreWorker;

View File

@@ -67,7 +67,7 @@ const WRITE_DELAY_MS = 1000 * 60 * 5; // once every 5 minutes
* <code>window.indexedDB</code> * <code>window.indexedDB</code>
* @param {string=} opts.dbName Optional database name. The same name must be used * @param {string=} opts.dbName Optional database name. The same name must be used
* to open the same database. * to open the same database.
* @param {string=} opts.workerScript Optional URL to a script to invooke a web * @param {string=} opts.workerScript Optional URL to a script to invoke a web
* worker with to run IndexedDB queries on the web worker. The IndexedDbStoreWorker * worker with to run IndexedDB queries on the web worker. The IndexedDbStoreWorker
* class is provided for this purpose and requires the application to provide a * class is provided for this purpose and requires the application to provide a
* trivial wrapper script around it. * trivial wrapper script around it.