Apply `retryFnIfNotJoined` to the rest of the endpoints
This commit is contained in:
parent
2c2ce3e656
commit
ae50a9f16f
|
@ -18,7 +18,6 @@ const {
|
||||||
fetchSuccessorInfo,
|
fetchSuccessorInfo,
|
||||||
} = require('../lib/matrix-utils/fetch-room-data');
|
} = require('../lib/matrix-utils/fetch-room-data');
|
||||||
const fetchEventsFromTimestampBackwards = require('../lib/matrix-utils/fetch-events-from-timestamp-backwards');
|
const fetchEventsFromTimestampBackwards = require('../lib/matrix-utils/fetch-events-from-timestamp-backwards');
|
||||||
const ensureRoomJoined = require('../lib/matrix-utils/ensure-room-joined');
|
|
||||||
const createRetryFnIfNotJoined = require('../lib/matrix-utils/create-retry-fn-if-not-joined');
|
const createRetryFnIfNotJoined = require('../lib/matrix-utils/create-retry-fn-if-not-joined');
|
||||||
const resolveRoomIdOrAlias = require('../lib/matrix-utils/resolve-room-id-or-alias');
|
const resolveRoomIdOrAlias = require('../lib/matrix-utils/resolve-room-id-or-alias');
|
||||||
const timestampToEvent = require('../lib/matrix-utils/timestamp-to-event');
|
const timestampToEvent = require('../lib/matrix-utils/timestamp-to-event');
|
||||||
|
@ -181,21 +180,32 @@ router.get(
|
||||||
// the time before we join and looking backwards.
|
// the time before we join and looking backwards.
|
||||||
const dateBeforeJoin = Date.now();
|
const dateBeforeJoin = Date.now();
|
||||||
|
|
||||||
// We have to wait for the room join to happen first before we can fetch
|
// Resolve the room ID without joining the room (optimistically assume that we're
|
||||||
// any of the additional room info or messages.
|
// already joined)
|
||||||
const roomId = await ensureRoomJoined(matrixAccessToken, roomIdOrAlias, {
|
let viaServers = parseViaServersFromUserInput(req.query.via);
|
||||||
viaServers: parseViaServersFromUserInput(req.query.via),
|
let roomId;
|
||||||
|
({ roomId, viaServers } = await resolveRoomIdOrAlias({
|
||||||
|
accessToken: matrixAccessToken,
|
||||||
|
roomIdOrAlias,
|
||||||
|
viaServers,
|
||||||
|
abortSignal: req.abortSignal,
|
||||||
|
}));
|
||||||
|
// And then we can always retry after joining if we fail somewhere
|
||||||
|
const retryFnIfNotJoined = createRetryFnIfNotJoined(matrixAccessToken, roomIdOrAlias, {
|
||||||
|
viaServers,
|
||||||
abortSignal: req.abortSignal,
|
abortSignal: req.abortSignal,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find the closest day to the current time with messages
|
// Find the closest day to the current time with messages
|
||||||
const { originServerTs } = await timestampToEvent({
|
const { originServerTs } = await retryFnIfNotJoined(() =>
|
||||||
accessToken: matrixAccessToken,
|
timestampToEvent({
|
||||||
roomId,
|
accessToken: matrixAccessToken,
|
||||||
ts: dateBeforeJoin,
|
roomId,
|
||||||
direction: DIRECTION.backward,
|
ts: dateBeforeJoin,
|
||||||
abortSignal: req.abortSignal,
|
direction: DIRECTION.backward,
|
||||||
});
|
abortSignal: req.abortSignal,
|
||||||
|
})
|
||||||
|
);
|
||||||
if (!originServerTs) {
|
if (!originServerTs) {
|
||||||
throw new StatusError(404, 'Unable to find day with history');
|
throw new StatusError(404, 'Unable to find day with history');
|
||||||
}
|
}
|
||||||
|
@ -203,8 +213,8 @@ router.get(
|
||||||
// Redirect to a day with messages
|
// Redirect to a day with messages
|
||||||
res.redirect(
|
res.redirect(
|
||||||
matrixPublicArchiveURLCreator.archiveUrlForDate(roomIdOrAlias, new Date(originServerTs), {
|
matrixPublicArchiveURLCreator.archiveUrlForDate(roomIdOrAlias, new Date(originServerTs), {
|
||||||
// We can avoid passing along the `via` query parameter because we already
|
// We can avoid passing along the `viaServers` because our server already knows
|
||||||
// joined the room above (see `ensureRoomJoined`).
|
// about the room given that we fetched data about it already.
|
||||||
//
|
//
|
||||||
//viaServers: parseViaServersFromUserInput(req.query.via),
|
//viaServers: parseViaServersFromUserInput(req.query.via),
|
||||||
})
|
})
|
||||||
|
@ -253,10 +263,18 @@ router.get(
|
||||||
`?timelineEndEventId must be a string or undefined but saw ${typeof timelineStartEventId}`
|
`?timelineEndEventId must be a string or undefined but saw ${typeof timelineStartEventId}`
|
||||||
);
|
);
|
||||||
|
|
||||||
// We have to wait for the room join to happen first before we can use the jump to
|
// Resolve the room ID without joining the room (optimistically assume that we're
|
||||||
// date endpoint (or any other Matrix endpoint)
|
// already joined)
|
||||||
const viaServers = parseViaServersFromUserInput(req.query.via);
|
let viaServers = parseViaServersFromUserInput(req.query.via);
|
||||||
const roomId = await ensureRoomJoined(matrixAccessToken, roomIdOrAlias, {
|
let roomId;
|
||||||
|
({ roomId, viaServers } = await resolveRoomIdOrAlias({
|
||||||
|
accessToken: matrixAccessToken,
|
||||||
|
roomIdOrAlias,
|
||||||
|
viaServers,
|
||||||
|
abortSignal: req.abortSignal,
|
||||||
|
}));
|
||||||
|
// And then we can always retry after joining if we fail somewhere
|
||||||
|
const retryFnIfNotJoined = createRetryFnIfNotJoined(matrixAccessToken, roomIdOrAlias, {
|
||||||
viaServers,
|
viaServers,
|
||||||
abortSignal: req.abortSignal,
|
abortSignal: req.abortSignal,
|
||||||
});
|
});
|
||||||
|
@ -298,28 +316,32 @@ router.get(
|
||||||
// Find the closest event to the given timestamp
|
// Find the closest event to the given timestamp
|
||||||
[{ eventId: eventIdForClosestEvent, originServerTs: tsForClosestEvent }, roomCreateEventId] =
|
[{ eventId: eventIdForClosestEvent, originServerTs: tsForClosestEvent }, roomCreateEventId] =
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
timestampToEvent({
|
retryFnIfNotJoined(() =>
|
||||||
accessToken: matrixAccessToken,
|
timestampToEvent({
|
||||||
roomId,
|
accessToken: matrixAccessToken,
|
||||||
ts: ts,
|
roomId,
|
||||||
direction: dir,
|
ts: ts,
|
||||||
// Since timestamps are untrusted and can be crafted to make loops in the
|
direction: dir,
|
||||||
// timeline. We use this as a signal to keep progressing from this event
|
// Since timestamps are untrusted and can be crafted to make loops in the
|
||||||
// regardless of what timestamp shenanigans are going on. See MSC3999
|
// timeline. We use this as a signal to keep progressing from this event
|
||||||
// (https://github.com/matrix-org/matrix-spec-proposals/pull/3999)
|
// regardless of what timestamp shenanigans are going on. See MSC3999
|
||||||
//
|
// (https://github.com/matrix-org/matrix-spec-proposals/pull/3999)
|
||||||
// TODO: Add tests for timestamp loops once Synapse supports MSC3999. We
|
//
|
||||||
// currently just have this set in case some server has this implemented in
|
// TODO: Add tests for timestamp loops once Synapse supports MSC3999. We
|
||||||
// the future but there currently is no implementation (as of 2023-04-17) and
|
// currently just have this set in case some server has this implemented in
|
||||||
// we can't have passing tests without a server implementation first.
|
// the future but there currently is no implementation (as of 2023-04-17) and
|
||||||
//
|
// we can't have passing tests without a server implementation first.
|
||||||
// TODO: This isn't implemented yet
|
//
|
||||||
fromCausalEventId,
|
// TODO: This isn't implemented yet
|
||||||
abortSignal: req.abortSignal,
|
fromCausalEventId,
|
||||||
}),
|
abortSignal: req.abortSignal,
|
||||||
removeMe_fetchRoomCreateEventId(matrixAccessToken, roomId, {
|
})
|
||||||
abortSignal: req.abortSignal,
|
),
|
||||||
}),
|
retryFnIfNotJoined(() =>
|
||||||
|
removeMe_fetchRoomCreateEventId(matrixAccessToken, roomId, {
|
||||||
|
abortSignal: req.abortSignal,
|
||||||
|
})
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Without MSC3999, we currently only detect one kind of loop where the
|
// Without MSC3999, we currently only detect one kind of loop where the
|
||||||
|
@ -444,14 +466,16 @@ router.get(
|
||||||
// for the actual room display that we redirect to from this route. No need for
|
// for the actual room display that we redirect to from this route. No need for
|
||||||
// us go out 100 messages, only for us to go backwards 100 messages again in the
|
// us go out 100 messages, only for us to go backwards 100 messages again in the
|
||||||
// next route.
|
// next route.
|
||||||
const messageResData = await getMessagesResponseFromEventId({
|
const messageResData = await retryFnIfNotJoined(() =>
|
||||||
accessToken: matrixAccessToken,
|
getMessagesResponseFromEventId({
|
||||||
roomId,
|
accessToken: matrixAccessToken,
|
||||||
eventId: eventIdForClosestEvent,
|
roomId,
|
||||||
dir: DIRECTION.forward,
|
eventId: eventIdForClosestEvent,
|
||||||
limit: archiveMessageLimit,
|
dir: DIRECTION.forward,
|
||||||
abortSignal: req.abortSignal,
|
limit: archiveMessageLimit,
|
||||||
});
|
abortSignal: req.abortSignal,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
if (!messageResData.chunk?.length) {
|
if (!messageResData.chunk?.length) {
|
||||||
throw new StatusError(
|
throw new StatusError(
|
||||||
|
@ -584,9 +608,11 @@ router.get(
|
||||||
predecessorRoomId,
|
predecessorRoomId,
|
||||||
predecessorLastKnownEventId,
|
predecessorLastKnownEventId,
|
||||||
predecessorViaServers,
|
predecessorViaServers,
|
||||||
} = await fetchPredecessorInfo(matrixAccessToken, roomId, {
|
} = await retryFnIfNotJoined(() =>
|
||||||
abortSignal: req.abortSignal,
|
fetchPredecessorInfo(matrixAccessToken, roomId, {
|
||||||
});
|
abortSignal: req.abortSignal,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
if (!predecessorRoomId) {
|
if (!predecessorRoomId) {
|
||||||
throw new StatusError(
|
throw new StatusError(
|
||||||
|
@ -595,18 +621,24 @@ router.get(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have to join the predecessor room before we can fetch the successor info
|
// We can always retry after joining if we fail somewhere
|
||||||
// (this could be our first time seeing the room)
|
const retryFnIfNotJoinedToPredecessorRoom = createRetryFnIfNotJoined(
|
||||||
await ensureRoomJoined(matrixAccessToken, predecessorRoomId, {
|
matrixAccessToken,
|
||||||
viaServers,
|
predecessorRoomId,
|
||||||
abortSignal: req.abortSignal,
|
{
|
||||||
});
|
viaServers,
|
||||||
|
abortSignal: req.abortSignal,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
successorRoomId: successorRoomIdForPredecessor,
|
successorRoomId: successorRoomIdForPredecessor,
|
||||||
successorSetTs: successorSetTsForPredecessor,
|
successorSetTs: successorSetTsForPredecessor,
|
||||||
} = await fetchSuccessorInfo(matrixAccessToken, predecessorRoomId, {
|
} = await retryFnIfNotJoinedToPredecessorRoom(() =>
|
||||||
abortSignal: req.abortSignal,
|
fetchSuccessorInfo(matrixAccessToken, predecessorRoomId, {
|
||||||
});
|
abortSignal: req.abortSignal,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
let tombstoneEventId;
|
let tombstoneEventId;
|
||||||
if (!predecessorLastKnownEventId) {
|
if (!predecessorLastKnownEventId) {
|
||||||
|
@ -617,13 +649,15 @@ router.get(
|
||||||
//
|
//
|
||||||
// We just assume this is the tombstone event ID but in any case it gets us to
|
// We just assume this is the tombstone event ID but in any case it gets us to
|
||||||
// an event that happened at the same time.
|
// an event that happened at the same time.
|
||||||
({ eventId: tombstoneEventId } = await timestampToEvent({
|
({ eventId: tombstoneEventId } = await retryFnIfNotJoinedToPredecessorRoom(() =>
|
||||||
accessToken: matrixAccessToken,
|
timestampToEvent({
|
||||||
roomId: predecessorRoomId,
|
accessToken: matrixAccessToken,
|
||||||
ts: successorSetTsForPredecessor,
|
roomId: predecessorRoomId,
|
||||||
direction: DIRECTION.backward,
|
ts: successorSetTsForPredecessor,
|
||||||
abortSignal: req.abortSignal,
|
direction: DIRECTION.backward,
|
||||||
}));
|
abortSignal: req.abortSignal,
|
||||||
|
})
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to continue from the tombstone event in the predecessor room because
|
// Try to continue from the tombstone event in the predecessor room because
|
||||||
|
@ -685,9 +719,11 @@ router.get(
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
} else if (dir === DIRECTION.forward) {
|
} else if (dir === DIRECTION.forward) {
|
||||||
const { successorRoomId } = await fetchSuccessorInfo(matrixAccessToken, roomId, {
|
const { successorRoomId } = await retryFnIfNotJoined(() =>
|
||||||
abortSignal: req.abortSignal,
|
fetchSuccessorInfo(matrixAccessToken, roomId, {
|
||||||
});
|
abortSignal: req.abortSignal,
|
||||||
|
})
|
||||||
|
);
|
||||||
if (successorRoomId) {
|
if (successorRoomId) {
|
||||||
// Jump to the successor room and continue at the first event of the room
|
// Jump to the successor room and continue at the first event of the room
|
||||||
res.redirect(
|
res.redirect(
|
||||||
|
@ -800,7 +836,7 @@ router.get(
|
||||||
viaServers,
|
viaServers,
|
||||||
abortSignal: req.abortSignal,
|
abortSignal: req.abortSignal,
|
||||||
}));
|
}));
|
||||||
|
// And then we can always retry after joining if we fail somewhere
|
||||||
const retryFnIfNotJoined = createRetryFnIfNotJoined(matrixAccessToken, roomIdOrAlias, {
|
const retryFnIfNotJoined = createRetryFnIfNotJoined(matrixAccessToken, roomIdOrAlias, {
|
||||||
viaServers,
|
viaServers,
|
||||||
abortSignal: req.abortSignal,
|
abortSignal: req.abortSignal,
|
||||||
|
@ -932,8 +968,8 @@ router.get(
|
||||||
// We purposely omit `scrollStartEventId` here because the canonical location
|
// We purposely omit `scrollStartEventId` here because the canonical location
|
||||||
// for any given event ID is the page it resides on.
|
// for any given event ID is the page it resides on.
|
||||||
//
|
//
|
||||||
// We can avoid passing along the `viaServers` because we already joined the
|
// We can avoid passing along the `viaServers` because our server already knows about
|
||||||
// room above (see `ensureRoomJoined`).
|
// the room given that we fetched data about it already.
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
shouldIndex,
|
shouldIndex,
|
||||||
|
|
Loading…
Reference in New Issue