You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-26 17:03:12 +03:00
DeviceList: bring save forward if necessary
If save is called with a delay that would want the save to happen sooner then the save we currently have scheduled, cancel the current save and schedule a new one for the sooner time.
This commit is contained in:
@@ -92,6 +92,12 @@ export default class DeviceList {
|
|||||||
|
|
||||||
// Promise resolved when device data is saved
|
// Promise resolved when device data is saved
|
||||||
this._savePromise = null;
|
this._savePromise = null;
|
||||||
|
// Function that resolves the save promise
|
||||||
|
this._resolveSavePromise = null;
|
||||||
|
// The time the save is scheduled for
|
||||||
|
this._savePromiseTime = null;
|
||||||
|
// The timer used to delay the save
|
||||||
|
this._saveTimer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -159,17 +165,42 @@ export default class DeviceList {
|
|||||||
if (!this._dirty) return Promise.resolve(false);
|
if (!this._dirty) return Promise.resolve(false);
|
||||||
if (delay === undefined) delay = 500;
|
if (delay === undefined) delay = 500;
|
||||||
|
|
||||||
if (this._savePromise === null) {
|
const targetTime = Date.now + delay;
|
||||||
|
if (this._savePromiseTime && targetTime < this._savePromiseTime) {
|
||||||
|
// There's a save scheduled but for after we would like: cancel
|
||||||
|
// it & schedule one for the time we want
|
||||||
|
clearTimeout(this._saveTimer);
|
||||||
|
this._saveTimer = null;
|
||||||
|
this._savePromiseTime = null;
|
||||||
|
// (but keep the save promise since whatever called save before
|
||||||
|
// will still want to know when the save is done)
|
||||||
|
}
|
||||||
|
|
||||||
|
let savePromise = this._savePromise;
|
||||||
|
if (savePromise === null) {
|
||||||
|
savePromise = new Promise((resolve, reject) => {
|
||||||
|
this._resolveSavePromise = resolve;
|
||||||
|
});
|
||||||
|
this._savePromise = savePromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._saveTimer === null) {
|
||||||
// Delay saves for a bit so we can aggregate multiple saves that happen
|
// Delay saves for a bit so we can aggregate multiple saves that happen
|
||||||
// in quick succession (eg. when a whole room's devices are marked as known)
|
// in quick succession (eg. when a whole room's devices are marked as known)
|
||||||
this._savePromise = Promise.delay(delay).then(() => {
|
const resolveSavePromise = this._resolveSavePromise;
|
||||||
|
this._savePromiseTime = targetTime;
|
||||||
|
this._saveTimer = setTimeout(() => {
|
||||||
console.log('Saving device tracking data at token ' + this._syncToken);
|
console.log('Saving device tracking data at token ' + this._syncToken);
|
||||||
// null out savePromise now (after the delay but before the write),
|
// null out savePromise now (after the delay but before the write),
|
||||||
// otherwise we could return the existing promise when the save has
|
// otherwise we could return the existing promise when the save has
|
||||||
// actually already happened. Likewise for the dirty flag.
|
// actually already happened. Likewise for the dirty flag.
|
||||||
|
this._savePromiseTime = null;
|
||||||
|
this._saveTimer = null;
|
||||||
this._savePromise = null;
|
this._savePromise = null;
|
||||||
|
this._resolveSavePromise = null;
|
||||||
|
|
||||||
this._dirty = false;
|
this._dirty = false;
|
||||||
return this._cryptoStore.doTxn(
|
this._cryptoStore.doTxn(
|
||||||
'readwrite', [IndexedDBCryptoStore.STORE_DEVICE_DATA], (txn) => {
|
'readwrite', [IndexedDBCryptoStore.STORE_DEVICE_DATA], (txn) => {
|
||||||
this._cryptoStore.storeEndToEndDeviceData({
|
this._cryptoStore.storeEndToEndDeviceData({
|
||||||
devices: this._devices,
|
devices: this._devices,
|
||||||
@@ -177,12 +208,12 @@ export default class DeviceList {
|
|||||||
syncToken: this._syncToken,
|
syncToken: this._syncToken,
|
||||||
}, txn);
|
}, txn);
|
||||||
},
|
},
|
||||||
);
|
).then(() => {
|
||||||
}).then(() => {
|
resolveSavePromise();
|
||||||
return true;
|
});
|
||||||
});
|
}, delay);
|
||||||
}
|
}
|
||||||
return this._savePromise;
|
return savePromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user