keep token in memory to compare stored token with after /messages

and don't look at response.start as it can be different as
the format can change after a server upgrade while
(still pointing at the same location)
This commit is contained in:
Bruno Windels 2023-02-10 14:08:35 +01:00
parent 9e28bdcc88
commit 7c1117ddd4
2 changed files with 9 additions and 6 deletions

View File

@ -350,7 +350,7 @@ export class BaseRoom extends EventEmitter {
fragmentIdComparer: this._fragmentIdComparer, fragmentIdComparer: this._fragmentIdComparer,
relationWriter relationWriter
}); });
gapResult = await gapWriter.writeFragmentFill(fragmentEntry, response, txn, log); gapResult = await gapWriter.writeFragmentFill(fragmentEntry, response, fragmentEntry.token, txn, log);
} catch (err) { } catch (err) {
txn.abort(); txn.abort();
throw err; throw err;

View File

@ -154,10 +154,13 @@ export class GapWriter {
return changedFragments; return changedFragments;
} }
async writeFragmentFill(fragmentEntry, response, txn, log) { /**
* @param {string} fromToken the token used to call /messages, to ensure it hasn't changed in storage
*/
async writeFragmentFill(fragmentEntry, response, fromToken, txn, log) {
const {fragmentId, direction} = fragmentEntry; const {fragmentId, direction} = fragmentEntry;
// chunk is in reverse-chronological order when backwards // chunk is in reverse-chronological order when backwards
const {chunk, start, state} = response; const {chunk, state} = response;
let {end} = response; let {end} = response;
if (!Array.isArray(chunk)) { if (!Array.isArray(chunk)) {
@ -174,8 +177,8 @@ export class GapWriter {
} }
fragmentEntry = fragmentEntry.withUpdatedFragment(fragment); fragmentEntry = fragmentEntry.withUpdatedFragment(fragment);
// check that the request was done with the token we are aware of (extra care to avoid timeline corruption) // check that the request was done with the token we are aware of (extra care to avoid timeline corruption)
if (fragmentEntry.token !== start) { if (fragmentEntry.token !== fromToken) {
throw new Error("start is not equal to prev_batch or next_batch"); throw new Error("The pagination token has changed locally while fetching messages.");
} }
// begin (or end) of timeline reached // begin (or end) of timeline reached
@ -263,7 +266,7 @@ export function tests() {
async function backfillAndWrite(mocks, fragmentEntry, limit) { async function backfillAndWrite(mocks, fragmentEntry, limit) {
const {txn, timelineMock, gapWriter} = mocks; const {txn, timelineMock, gapWriter} = mocks;
const messageResponse = timelineMock.messages(fragmentEntry.token, undefined, fragmentEntry.direction.asApiString(), limit); const messageResponse = timelineMock.messages(fragmentEntry.token, undefined, fragmentEntry.direction.asApiString(), limit);
await gapWriter.writeFragmentFill(fragmentEntry, messageResponse, txn, logger); await gapWriter.writeFragmentFill(fragmentEntry, messageResponse, fragmentEntry.token, txn, logger);
} }
async function allFragmentEvents(mocks, fragmentId) { async function allFragmentEvents(mocks, fragmentId) {