You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-28 05:03:59 +03:00
Use /members api for lazy loading
This commit is a substantial change, as /members returns state events, not profile information as /joined_members, and this allows to simplify the implementation quite a bit. We can assume again all members have a state event associated with it. I also changed most of the naming of lazy loaded members to out-of-band members to reflect that this is the relevant bit for most of the code, that the members didn't come through /sync but through another channel. This commit also addresses the race condition between /(joined_)members and /sync. /members returns the members at the point in the timeline at a given event id. Members are loaded at the last event in the live timeline, and all members that come in from sync in the mean time are marked as superseding the out of band members, so they won't be overwritten, even if the timeline is reset in the mean time. Members are also marked if they originate from an out-of-band channel (/members) so they can be stored accordingly (future PR). The loading status is kept in room state now, as this made resolving the race condition easier. One consequence is that the status needs to be shared across cloned instances of RoomState. When resetting the timeline (and cloning the room state) while lazy loading is in progress, one of the RoomStates could be left in progress indefinitely. Though that is more for clarity than avoiding any actual bugs.
This commit is contained in:
@@ -764,36 +764,14 @@ MatrixClient.prototype.getRoom = function(roomId) {
|
||||
*/
|
||||
MatrixClient.prototype.loadRoomMembersIfNeeded = async function(roomId) {
|
||||
const room = this.getRoom(roomId);
|
||||
if (!room || !room.membersNeedLoading()) {
|
||||
if (!room || !room.needsOutOfBandMembers()) {
|
||||
return;
|
||||
}
|
||||
// XXX: we should make sure that the members we get back represent the
|
||||
// room state at a given point in time. The plan is to do this by
|
||||
// passing the current next_batch sync token to the endpoint we use
|
||||
// to fetch the members. For now, this is a prototype that uses
|
||||
// the /joined_members api, which only tells us about the joined members
|
||||
// (not invites for example) and does not support this synchronization.
|
||||
// So there is a race condition here between the current /sync call
|
||||
// and the /joined_members call: if the have conflicting information, which one
|
||||
// represents the most recent state?
|
||||
//
|
||||
// Addressing this race condition and the fact that this only tells us about
|
||||
// joined members is a prerequisite for taking this out of the prototype stage and
|
||||
// enabling the feature flag (feature_lazyloading) that
|
||||
// the call to this method is behind.
|
||||
const joinedMembersPromise = this.joinedMembers(roomId);
|
||||
const membersPromise = joinedMembersPromise.then((profiles) => {
|
||||
return Object.entries(profiles.joined).map(([userId, profile]) => {
|
||||
return {
|
||||
userId: userId,
|
||||
avatarUrl: profile.avatar_url,
|
||||
displayName: profile.display_name,
|
||||
membership: "join", // as we need to support invitees as well
|
||||
// in the future, already include but hardcode it
|
||||
};
|
||||
});
|
||||
});
|
||||
await room.setLazyLoadedMembers(membersPromise);
|
||||
|
||||
const lastEventId = room.getLastEventId();
|
||||
const responsePromise = this.members(roomId, "join", "leave", lastEventId);
|
||||
const eventsPromise = responsePromise.then((response) => response.chunk);
|
||||
await room.loadOutOfBandMembers(eventsPromise);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user