open storage transactions synchronously

this (almost) makes it work in some browsers that otherwise
have throw a TransactionInactiveError on the first operation
you try to do on a store.
This commit is contained in:
Bruno Windels 2020-09-25 16:42:41 +02:00
parent d759e1429f
commit 76381fbca1
16 changed files with 48 additions and 48 deletions

View file

@ -80,7 +80,7 @@ export class DeviceMessageHandler {
if (!this._olmDecryption) {
return;
}
const readTxn = await this._storage.readTxn([this._storage.storeNames.session]);
const readTxn = this._storage.readTxn([this._storage.storeNames.session]);
const pendingEvents = await this._getPendingEvents(readTxn);
if (pendingEvents.length === 0) {
return;
@ -91,7 +91,7 @@ export class DeviceMessageHandler {
for (const err of decryptChanges.errors) {
console.warn("decryption failed for event", err, err.event);
}
const txn = await this._storage.readWriteTxn([
const txn = this._storage.readWriteTxn([
// both to remove the pending events and to modify the olm account
this._storage.storeNames.session,
this._storage.storeNames.olmSessions,

View file

@ -164,13 +164,13 @@ export class Session {
}
const key = await ssssKeyFromCredential(type, credential, this._storage, this._cryptoDriver, this._olm);
// and create session backup, which needs to read from accountData
const readTxn = await this._storage.readTxn([
const readTxn = this._storage.readTxn([
this._storage.storeNames.accountData,
]);
await this._createSessionBackup(key, readTxn);
// only after having read a secret, write the key
// as we only find out if it was good if the MAC verification succeeds
const writeTxn = await this._storage.readWriteTxn([
const writeTxn = this._storage.readWriteTxn([
this._storage.storeNames.session,
]);
try {
@ -217,7 +217,7 @@ export class Session {
await this._e2eeAccount.uploadKeys(this._storage);
await this._deviceMessageHandler.decryptPending(this.rooms);
const txn = await this._storage.readTxn([
const txn = this._storage.readTxn([
this._storage.storeNames.session,
this._storage.storeNames.accountData,
]);
@ -231,7 +231,7 @@ export class Session {
}
async load() {
const txn = await this._storage.readTxn([
const txn = this._storage.readTxn([
this._storage.storeNames.session,
this._storage.storeNames.roomSummary,
this._storage.storeNames.roomMembers,
@ -276,7 +276,7 @@ export class Session {
async start(lastVersionResponse) {
if (lastVersionResponse) {
// store /versions response
const txn = await this._storage.readWriteTxn([
const txn = this._storage.readWriteTxn([
this._storage.storeNames.session
]);
txn.session.set("serverVersions", lastVersionResponse);
@ -284,7 +284,7 @@ export class Session {
await txn.complete();
}
const opsTxn = await this._storage.readWriteTxn([
const opsTxn = this._storage.readWriteTxn([
this._storage.storeNames.operations
]);
const operations = await opsTxn.operations.getAll();

View file

@ -184,7 +184,7 @@ export class Sync {
const roomStates = this._parseRoomsResponse(response.rooms, isInitialSync);
await this._prepareRooms(roomStates);
let sessionChanges;
const syncTxn = await this._openSyncTxn();
const syncTxn = this._openSyncTxn();
try {
await Promise.all(roomStates.map(async rs => {
console.log(` * applying sync response to room ${rs.room.id} ...`);
@ -221,24 +221,24 @@ export class Sync {
};
}
async _openPrepareSyncTxn() {
_openPrepareSyncTxn() {
const storeNames = this._storage.storeNames;
return await this._storage.readTxn([
return this._storage.readTxn([
storeNames.inboundGroupSessions,
]);
}
async _prepareRooms(roomStates) {
const prepareTxn = await this._openPrepareSyncTxn();
const prepareTxn = this._openPrepareSyncTxn();
await Promise.all(roomStates.map(async rs => {
rs.preparation = await rs.room.prepareSync(rs.roomResponse, rs.membership, prepareTxn);
}));
await Promise.all(roomStates.map(rs => rs.room.afterPrepareSync(rs.preparation)));
}
async _openSyncTxn() {
_openSyncTxn() {
const storeNames = this._storage.storeNames;
return await this._storage.readWriteTxn([
return this._storage.readWriteTxn([
storeNames.session,
storeNames.roomSummary,
storeNames.roomState,

View file

@ -45,7 +45,7 @@ export class Account {
}
const pickledAccount = account.pickle(pickleKey);
const areDeviceKeysUploaded = false;
const txn = await storage.readWriteTxn([
const txn = storage.readWriteTxn([
storage.storeNames.session
]);
try {
@ -212,7 +212,7 @@ export class Account {
}
async _updateSessionStorage(storage, callback) {
const txn = await storage.readWriteTxn([
const txn = storage.readWriteTxn([
storage.storeNames.session
]);
try {

View file

@ -68,7 +68,7 @@ export class DeviceTracker {
}
const memberList = await room.loadMemberList();
try {
const txn = await this._storage.readWriteTxn([
const txn = this._storage.readWriteTxn([
this._storage.storeNames.roomSummary,
this._storage.storeNames.userIdentities,
]);
@ -149,7 +149,7 @@ export class DeviceTracker {
}).response();
const verifiedKeysPerUser = this._filterVerifiedDeviceKeys(deviceKeyResponse["device_keys"]);
const txn = await this._storage.readWriteTxn([
const txn = this._storage.readWriteTxn([
this._storage.storeNames.userIdentities,
this._storage.storeNames.deviceIdentities,
]);
@ -252,7 +252,7 @@ export class DeviceTracker {
* @return {[type]} [description]
*/
async devicesForTrackedRoom(roomId, hsApi) {
const txn = await this._storage.readTxn([
const txn = this._storage.readTxn([
this._storage.storeNames.roomMembers,
this._storage.storeNames.userIdentities,
]);
@ -268,7 +268,7 @@ export class DeviceTracker {
}
async devicesForRoomMembers(roomId, userIds, hsApi) {
const txn = await this._storage.readTxn([
const txn = this._storage.readTxn([
this._storage.storeNames.userIdentities,
]);
return await this._devicesForUserIds(roomId, userIds, txn, hsApi);
@ -298,7 +298,7 @@ export class DeviceTracker {
queriedDevices = await this._queryKeys(outdatedIdentities.map(i => i.userId), hsApi);
}
const deviceTxn = await this._storage.readTxn([
const deviceTxn = this._storage.readTxn([
this._storage.storeNames.deviceIdentities,
]);
const devicesPerUser = await Promise.all(upToDateIdentities.map(identity => {

View file

@ -183,7 +183,7 @@ export class RoomEncryption {
console.warn("Got session key back from backup with different sender key, ignoring", {session, senderKey});
return;
}
const txn = await this._storage.readWriteTxn([this._storage.storeNames.inboundGroupSessions]);
const txn = this._storage.readWriteTxn([this._storage.storeNames.inboundGroupSessions]);
let roomKey;
try {
roomKey = await this._megolmDecryption.addRoomKeyFromBackup(
@ -273,7 +273,7 @@ export class RoomEncryption {
const userIds = Array.from(devices.reduce((set, device) => set.add(device.userId), new Set()));
// store operation for room key share, in case we don't finish here
const writeOpTxn = await this._storage.readWriteTxn([this._storage.storeNames.operations]);
const writeOpTxn = this._storage.readWriteTxn([this._storage.storeNames.operations]);
let operationId;
try {
operationId = this._writeRoomKeyShareOperation(roomKeyMessage, userIds, writeOpTxn);
@ -290,7 +290,7 @@ export class RoomEncryption {
await this._sendRoomKey(roomKeyMessage, devices, hsApi);
// remove the operation
const removeOpTxn = await this._storage.readWriteTxn([this._storage.storeNames.operations]);
const removeOpTxn = this._storage.readWriteTxn([this._storage.storeNames.operations]);
try {
removeOpTxn.operations.remove(operationId);
} catch (err) {
@ -329,7 +329,7 @@ export class RoomEncryption {
this._isFlushingRoomKeyShares = true;
try {
if (!operations) {
const txn = await this._storage.readTxn([this._storage.storeNames.operations]);
const txn = this._storage.readTxn([this._storage.storeNames.operations]);
operations = await txn.operations.getAllByTypeAndScope("share_room_key", this._room.id);
}
for (const operation of operations) {
@ -339,7 +339,7 @@ export class RoomEncryption {
}
const devices = await this._deviceTracker.devicesForRoomMembers(this._room.id, operation.userIds, hsApi);
await this._sendRoomKey(operation.roomKeyMessage, devices, hsApi);
const removeTxn = await this._storage.readWriteTxn([this._storage.storeNames.operations]);
const removeTxn = this._storage.readWriteTxn([this._storage.storeNames.operations]);
try {
removeTxn.operations.remove(operation.id);
} catch (err) {

View file

@ -54,7 +54,7 @@ export class Encryption {
async encrypt(roomId, type, content, encryptionParams) {
let session = new this._olm.OutboundGroupSession();
try {
const txn = await this._storage.readWriteTxn([
const txn = this._storage.readWriteTxn([
this._storage.storeNames.inboundGroupSessions,
this._storage.storeNames.outboundGroupSessions,
]);

View file

@ -67,7 +67,7 @@ export class Decryption {
return this._senderKeyLock.takeLock(senderKey);
}));
try {
const readSessionsTxn = await this._storage.readTxn([this._storage.storeNames.olmSessions]);
const readSessionsTxn = this._storage.readTxn([this._storage.storeNames.olmSessions]);
// decrypt events for different sender keys in parallel
const senderKeyOperations = await Promise.all(Array.from(eventsPerSenderKey.entries()).map(([senderKey, events]) => {
return this._decryptAllForSenderKey(senderKey, events, timestamp, readSessionsTxn);

View file

@ -98,7 +98,7 @@ export class Encryption {
}
async _findExistingSessions(devices) {
const txn = await this._storage.readTxn([this._storage.storeNames.olmSessions]);
const txn = this._storage.readTxn([this._storage.storeNames.olmSessions]);
const sessionIdsForDevice = await Promise.all(devices.map(async device => {
return await txn.olmSessions.getSessionIds(device.curve25519Key);
}));
@ -213,7 +213,7 @@ export class Encryption {
}
async _loadSessions(encryptionTargets) {
const txn = await this._storage.readTxn([this._storage.storeNames.olmSessions]);
const txn = this._storage.readTxn([this._storage.storeNames.olmSessions]);
// given we run loading in parallel, there might still be some
// storage requests that will finish later once one has failed.
// those should not allocate a session anymore.
@ -239,7 +239,7 @@ export class Encryption {
}
async _storeSessions(encryptionTargets, timestamp) {
const txn = await this._storage.readWriteTxn([this._storage.storeNames.olmSessions]);
const txn = this._storage.readWriteTxn([this._storage.storeNames.olmSessions]);
try {
for (const target of encryptionTargets) {
const sessionEntry = createSessionEntry(

View file

@ -82,7 +82,7 @@ export class Room extends EventEmitter {
let retryEntries;
if (retryEventIds) {
retryEntries = [];
txn = await this._storage.readTxn(stores);
txn = this._storage.readTxn(stores);
for (const eventId of retryEventIds) {
const storageEntry = await txn.timelineEvents.getByEventId(this._roomId, eventId);
if (storageEntry) {
@ -99,7 +99,7 @@ export class Room extends EventEmitter {
// check we have not already decrypted the most recent event in the room
// otherwise we know that the messages for this room key will not update the room summary
if (!sinceEventKey || !sinceEventKey.equals(this._syncWriter.lastMessageKey)) {
txn = await this._storage.readTxn(stores.concat(this._storage.storeNames.timelineFragments));
txn = this._storage.readTxn(stores.concat(this._storage.storeNames.timelineFragments));
const candidateEntries = await this._readRetryDecryptCandidateEntries(sinceEventKey, txn);
retryEntries = this._roomEncryption.findAndCacheEntriesForRoomKey(roomKey, candidateEntries);
}
@ -138,7 +138,7 @@ export class Room extends EventEmitter {
_decryptEntries(source, entries, inboundSessionTxn = null) {
const request = new DecryptionRequest(async r => {
if (!inboundSessionTxn) {
inboundSessionTxn = await this._storage.readTxn([this._storage.storeNames.inboundGroupSessions]);
inboundSessionTxn = this._storage.readTxn([this._storage.storeNames.inboundGroupSessions]);
}
if (r.cancelled) return;
const events = entries.filter(entry => {
@ -155,7 +155,7 @@ export class Room extends EventEmitter {
// read to fetch devices if timeline is open
stores.push(this._storage.storeNames.deviceIdentities);
}
const writeTxn = await this._storage.readWriteTxn(stores);
const writeTxn = this._storage.readWriteTxn(stores);
let decryption;
try {
decryption = await changes.write(writeTxn);
@ -387,7 +387,7 @@ export class Room extends EventEmitter {
}
}).response();
const txn = await this._storage.readWriteTxn([
const txn = this._storage.readWriteTxn([
this._storage.storeNames.pendingEvents,
this._storage.storeNames.timelineEvents,
this._storage.storeNames.timelineFragments,
@ -490,7 +490,7 @@ export class Room extends EventEmitter {
async _getLastEventId() {
const lastKey = this._syncWriter.lastMessageKey;
if (lastKey) {
const txn = await this._storage.readTxn([
const txn = this._storage.readTxn([
this._storage.storeNames.timelineEvents,
]);
const eventEntry = await txn.timelineEvents.get(this._roomId, lastKey);
@ -511,7 +511,7 @@ export class Room extends EventEmitter {
async clearUnread() {
if (this.isUnread || this.notificationCount) {
const txn = await this._storage.readWriteTxn([
const txn = this._storage.readWriteTxn([
this._storage.storeNames.roomSummary,
]);
let data;

View file

@ -272,7 +272,7 @@ export class RoomSummary {
if (data === this._data) {
return false;
}
const txn = await storage.readWriteTxn([
const txn = storage.readWriteTxn([
storage.storeNames.roomSummary,
]);
try {

View file

@ -18,7 +18,7 @@ limitations under the License.
import {RoomMember} from "./RoomMember.js";
async function loadMembers({roomId, storage}) {
const txn = await storage.readTxn([
const txn = storage.readTxn([
storage.storeNames.roomMembers,
]);
const memberDatas = await txn.roomMembers.getAll(roomId);
@ -33,7 +33,7 @@ async function fetchMembers({summary, syncToken, roomId, hsApi, storage, setChan
const memberResponse = await hsApi.members(roomId, {at: syncToken}).response();
const txn = await storage.readWriteTxn([
const txn = storage.readWriteTxn([
storage.storeNames.roomSummary,
storage.storeNames.roomMembers,
]);

View file

@ -129,7 +129,7 @@ export class SendQueue {
}
async _tryUpdateEvent(pendingEvent) {
const txn = await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);
const txn = this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);
console.log("_tryUpdateEvent: got txn");
try {
// pendingEvent might have been removed already here
@ -151,7 +151,7 @@ export class SendQueue {
async _createAndStoreEvent(eventType, content) {
console.log("_createAndStoreEvent");
const txn = await this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);
const txn = this._storage.readWriteTxn([this._storage.storeNames.pendingEvents]);
let pendingEvent;
try {
const pendingEventsStore = txn.pendingEvents;

View file

@ -108,14 +108,14 @@ export class TimelineReader {
readFrom(eventKey, direction, amount) {
return new ReaderRequest(async r => {
const txn = await this._openTxn();
const txn = this._openTxn();
return await this._readFrom(eventKey, direction, amount, r, txn);
});
}
readFromEnd(amount) {
return new ReaderRequest(async r => {
const txn = await this._openTxn();
const txn = this._openTxn();
const liveFragment = await txn.timelineFragments.liveFragment(this._roomId);
let entries;
// room hasn't been synced yet

View file

@ -19,7 +19,7 @@ import {keyFromPassphrase} from "./passphrase.js";
import {keyFromRecoveryKey} from "./recoveryKey.js";
async function readDefaultKeyDescription(storage) {
const txn = await storage.readTxn([
const txn = storage.readTxn([
storage.storeNames.accountData
]);
const defaultKeyEvent = await txn.accountData.get("m.secret_storage.default_key");

View file

@ -34,7 +34,7 @@ export class Storage {
}
}
async readTxn(storeNames) {
readTxn(storeNames) {
this._validateStoreNames(storeNames);
try {
const txn = this._db.transaction(storeNames, "readonly");
@ -44,7 +44,7 @@ export class Storage {
}
}
async readWriteTxn(storeNames) {
readWriteTxn(storeNames) {
this._validateStoreNames(storeNames);
try {
const txn = this._db.transaction(storeNames, "readwrite");