forked from mystiq/hydrogen-web
only apply sync changes in session once txn is committed
This commit is contained in:
parent
177b03915d
commit
fc741272ba
2 changed files with 63 additions and 5 deletions
|
@ -77,11 +77,19 @@ export default class Session {
|
||||||
return room;
|
return room;
|
||||||
}
|
}
|
||||||
|
|
||||||
persistSync(syncToken, syncFilterId, accountData, txn) {
|
writeSync(syncToken, syncFilterId, accountData, txn) {
|
||||||
if (syncToken !== this._session.syncToken) {
|
if (syncToken !== this._session.syncToken) {
|
||||||
this._session.syncToken = syncToken;
|
// don't modify this._session because transaction might still fail
|
||||||
this._session.syncFilterId = syncFilterId;
|
const newSessionData = Object.assign({}, this._session, {syncToken, syncFilterId});
|
||||||
txn.session.set(this._session);
|
txn.session.set(newSessionData);
|
||||||
|
return newSessionData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
afterSync(newSessionData) {
|
||||||
|
if (newSessionData) {
|
||||||
|
// sync transaction succeeded, modify object state now
|
||||||
|
this._session = newSessionData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,3 +105,51 @@ export default class Session {
|
||||||
return this._user;
|
return this._user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function tests() {
|
||||||
|
function createStorageMock(session, pendingEvents) {
|
||||||
|
return {
|
||||||
|
readTxn() {
|
||||||
|
return Promise.resolve({
|
||||||
|
session: {
|
||||||
|
get() {
|
||||||
|
return Promise.resolve(Object.assign({}, session));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pendingEvents: {
|
||||||
|
getAll() {
|
||||||
|
return Promise.resolve(pendingEvents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"session data is not modified until after sync": async (assert) => {
|
||||||
|
const session = new Session({storage: createStorageMock({
|
||||||
|
syncToken: "a",
|
||||||
|
syncFilterId: 5,
|
||||||
|
})});
|
||||||
|
await session.load();
|
||||||
|
let txnSetCalled = false;
|
||||||
|
const syncTxn = {
|
||||||
|
session: {
|
||||||
|
set({syncToken, syncFilterId}) {
|
||||||
|
txnSetCalled = true;
|
||||||
|
assert.equals(syncToken, "b");
|
||||||
|
assert.equals(syncFilterId, 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const newSessionData = session.writeSync("b", 6, {}, syncTxn);
|
||||||
|
assert(txnSetCalled);
|
||||||
|
assert.equals(session.syncToken, "a");
|
||||||
|
assert.equals(session.syncFilterId, 5);
|
||||||
|
session.afterSync(newSessionData);
|
||||||
|
assert.equals(session.syncToken, "b");
|
||||||
|
assert.equals(session.syncFilterId, 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -85,8 +85,9 @@ export default class Sync extends EventEmitter {
|
||||||
storeNames.pendingEvents,
|
storeNames.pendingEvents,
|
||||||
]);
|
]);
|
||||||
const roomChanges = [];
|
const roomChanges = [];
|
||||||
|
let sessionChanges;
|
||||||
try {
|
try {
|
||||||
this._session.persistSync(syncToken, syncFilterId, response.account_data, syncTxn);
|
sessionChanges = this._session.writeSync(syncToken, syncFilterId, response.account_data, syncTxn);
|
||||||
// to_device
|
// to_device
|
||||||
// presence
|
// presence
|
||||||
if (response.rooms) {
|
if (response.rooms) {
|
||||||
|
@ -116,6 +117,7 @@ export default class Sync extends EventEmitter {
|
||||||
console.error("unable to commit sync tranaction");
|
console.error("unable to commit sync tranaction");
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
this._session.afterSync(sessionChanges);
|
||||||
// emit room related events after txn has been closed
|
// emit room related events after txn has been closed
|
||||||
for(let {room, changes} of roomChanges) {
|
for(let {room, changes} of roomChanges) {
|
||||||
room.emitSync(changes);
|
room.emitSync(changes);
|
||||||
|
|
Loading…
Reference in a new issue