Fix timeline race

A race between two calls to Room.openTimeline() would cause the second
call to return the timeline before it has completely loaded.
This commit is contained in:
RMidhunSuresh 2023-04-18 21:53:49 +05:30
parent 82502e3bb1
commit 644f1af88c

View File

@ -59,6 +59,7 @@ export class BaseRoom extends EventEmitter {
this._powerLevels = null; this._powerLevels = null;
this._powerLevelLoading = null; this._powerLevelLoading = null;
this._observedMembers = null; this._observedMembers = null;
this._timelineLoadPromise = null;
} }
async observeStateType(type, txn = undefined) { async observeStateType(type, txn = undefined) {
@ -545,6 +546,11 @@ export class BaseRoom extends EventEmitter {
return this._platform.logger.wrapOrRun(log, "open timeline", async log => { return this._platform.logger.wrapOrRun(log, "open timeline", async log => {
log.set("id", this.id); log.set("id", this.id);
if (this._timeline) { if (this._timeline) {
/**
* It's possible that timeline was created but timeline.load() has not yet finished.
* We only return the timeline when it has completely loaded!
*/
await this._timelineLoadPromise;
log.log({ l: "Returning existing timeline" }); log.log({ l: "Returning existing timeline" });
return this._timeline; return this._timeline;
} }
@ -568,7 +574,8 @@ export class BaseRoom extends EventEmitter {
if (this._roomEncryption) { if (this._roomEncryption) {
this._timeline.enableEncryption(this._decryptEntries.bind(this, DecryptionSource.Timeline)); this._timeline.enableEncryption(this._decryptEntries.bind(this, DecryptionSource.Timeline));
} }
await this._timeline.load(this._user, this.membership, log); this._timelineLoadPromise = this._timeline.load(this._user, this.membership, log);
await this._timelineLoadPromise;
} catch (err) { } catch (err) {
// this also clears this._timeline in the closeCallback // this also clears this._timeline in the closeCallback
this._timeline.dispose(); this._timeline.dispose();