store sync token and filter id under the same key in session

as they are updated together
This commit is contained in:
Bruno Windels 2020-08-27 14:36:50 +02:00
parent 14b27f81fe
commit 09a018ade1
2 changed files with 21 additions and 33 deletions

View file

@ -24,8 +24,7 @@ export class Session {
constructor({storage, hsApi, sessionInfo}) { constructor({storage, hsApi, sessionInfo}) {
this._storage = storage; this._storage = storage;
this._hsApi = hsApi; this._hsApi = hsApi;
this._syncToken = null; this._syncInfo = null;
this._syncFilterId = null;
this._sessionInfo = sessionInfo; this._sessionInfo = sessionInfo;
this._rooms = new ObservableMap(); this._rooms = new ObservableMap();
this._sendScheduler = new SendScheduler({hsApi, backoff: new RateLimitingBackoff()}); this._sendScheduler = new SendScheduler({hsApi, backoff: new RateLimitingBackoff()});
@ -43,12 +42,7 @@ export class Session {
this._storage.storeNames.pendingEvents, this._storage.storeNames.pendingEvents,
]); ]);
// restore session object // restore session object
const [syncToken, syncFilterId] = await Promise.all([ this._syncInfo = await txn.session.get("sync");
txn.session.get("syncToken"),
txn.session.get("syncFilterId")
]);
this._syncToken = syncToken;
this._syncFilterId = syncFilterId;
const pendingEventsByRoomId = await this._getPendingEventsByRoom(txn); const pendingEventsByRoomId = await this._getPendingEventsByRoom(txn);
// load rooms // load rooms
const rooms = await txn.roomSummary.getAll(); const rooms = await txn.roomSummary.getAll();
@ -115,28 +109,27 @@ export class Session {
} }
writeSync(syncToken, syncFilterId, accountData, txn) { writeSync(syncToken, syncFilterId, accountData, txn) {
if (syncToken !== this._syncToken) { if (syncToken !== this.syncToken) {
const syncInfo = {token: syncToken, filterId: syncFilterId};
// don't modify `this` because transaction might still fail // don't modify `this` because transaction might still fail
txn.session.set("syncToken", syncToken); txn.session.set("sync", syncInfo);
txn.session.set("syncFilterId", syncFilterId); return syncInfo;
return {syncToken, syncFilterId};
} }
} }
afterSync(changes) { afterSync(syncInfo) {
if (changes) { if (syncInfo) {
// sync transaction succeeded, modify object state now // sync transaction succeeded, modify object state now
this._syncToken = changes.syncToken; this._syncInfo = syncInfo;
this._syncFilterId = changes.syncFilterId;
} }
} }
get syncToken() { get syncToken() {
return this._syncToken; return this._syncInfo?.token;
} }
get syncFilterId() { get syncFilterId() {
return this._syncFilterId; return this._syncInfo?.filterId;
} }
get user() { get user() {
@ -173,28 +166,23 @@ export function tests() {
return { return {
"session data is not modified until after sync": async (assert) => { "session data is not modified until after sync": async (assert) => {
const session = new Session({storage: createStorageMock({ const session = new Session({storage: createStorageMock({
syncToken: "a", sync: {token: "a", filterId: 5}
syncFilterId: 5,
}), sessionInfo: {userId: ""}}); }), sessionInfo: {userId: ""}});
await session.load(); await session.load();
let syncTokenSet = false; let syncSet = false;
let syncFilterIdSet = false;
const syncTxn = { const syncTxn = {
session: { session: {
set(key, value) { set(key, value) {
if (key === "syncToken") { if (key === "sync") {
assert.equal(value, "b"); assert.equal(value.token, "b");
syncTokenSet = true; assert.equal(value.filterId, 6);
} else if (key === "syncFilterId") { syncSet = true;
assert.equal(value, 6);
syncFilterIdSet = true;
} }
} }
} }
}; };
const newSessionData = session.writeSync("b", 6, {}, syncTxn); const newSessionData = session.writeSync("b", 6, {}, syncTxn);
assert(syncTokenSet); assert(syncSet);
assert(syncFilterIdSet);
assert.equal(session.syncToken, "a"); assert.equal(session.syncToken, "a");
assert.equal(session.syncFilterId, 5); assert.equal(session.syncFilterId, 5);
session.afterSync(newSessionData); session.afterSync(newSessionData);

View file

@ -54,10 +54,10 @@ async function migrateSession(db, txn) {
const entry = await reqAsPromise(session.get(PRE_MIGRATION_KEY)); const entry = await reqAsPromise(session.get(PRE_MIGRATION_KEY));
if (entry) { if (entry) {
session.delete(PRE_MIGRATION_KEY); session.delete(PRE_MIGRATION_KEY);
const {syncToken, syncFilterId, serverVersions} = entry.value;
const store = new SessionStore(session); const store = new SessionStore(session);
for (const [key, value] of Object.entries(entry.value)) { store.set("sync", {token: syncToken, filterId: syncFilterId});
store.set(key, value); store.set("serverVersions", serverVersions);
}
} }
} catch (err) { } catch (err) {
txn.abort(); txn.abort();