Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reword GatewayMUCMembership storage to significantly speed up common operations #293

Merged
merged 2 commits into from
Sep 24, 2021

Conversation

tadzik
Copy link
Contributor

@tadzik tadzik commented Sep 22, 2021

The biggest winners here are addMatrixMember() and removeMatrixMember(),
which were a hotpath of updateMatrixMemberListForRoom, called upon xmpp users
joining matrix rooms, which used to lock up the process completely for
large rooms.

On a local test with a 3000-person room, the joins went down from ~500ms
to ~200 and then ~50 once the caches warm up. The remaining time seems
to be mostly spent on IO (sending actual XMPP presence updates), and the
offending code disappears completely from a profiler output – hopefully
meaning that the bridge will have ample time to deal with other tasks
instead of locking up completely like it used to.

There are some remaining bits that iterate on indexable member lists,
though they don't seem to be a measurable performance problem for now,
so I left them as they are – but easily identifyable with the menacing
Array.from().

@tadzik tadzik requested a review from a team September 22, 2021 14:02
…operations

The biggest winners here are addMatrixMember() and removeMatrixMember(),
which were a hotpath of updateMatrixMemberListForRoom, called upon xmpp users
joining matrix rooms, which used to lock up the process completely for
large rooms.

On a local test with a 3000-person room, the joins went down from ~500ms
to ~200 and then ~50 once the caches warm up. The remaining time *seems*
to be mostly spent on IO (sending actual XMPP presence updates), and the
offending code disappears completely from a profiler output – hopefully
meaning that the bridge will have ample time to deal with other tasks
instead of locking up completely like it used to.

There are some remaining bits that iterate on indexable member lists,
though they don't seem to be a measurable performance problem for now,
so I left them as they are – but easily identifyable with the menacing
Array.from().
@@ -49,11 +73,14 @@ export class GatewayMUCMembership {
}

public getMemberByAnonJid<G extends IGatewayMember>(chatName: string, anonJid: string): G|undefined {
return this.getMembers(chatName).find((user) => user.anonymousJid.toString() === anonJid) as G;
return Array.from(this.getMembers(chatName)).find((user) => user.anonymousJid.toString() === anonJid) as G;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't believe JS doesn't support find/filter on iterators – straight up encouraging you to create this sort of giant Arrays just to throw them away a moment later.

I didn't add more indexes to ChatMembers for these though, since I was unable to make these functions show up in the profiler output at all (it drops everything that didn't exceed 1% of its parent's runtime).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 1% is fine but yeah the inability to iterate on sets is, cough, awful. Almost tempted to use a utility library...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was looking for something in our existing dependency chain, but nothing caught me eye. Someday... :)

Copy link
Collaborator

@Half-Shot Half-Shot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Common sense improvements, thanks!

@@ -0,0 +1 @@
Speed up joins for large rooms, preventing them from locking up the process
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(for xmpp gateways only)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done :)

@@ -49,11 +73,14 @@ export class GatewayMUCMembership {
}

public getMemberByAnonJid<G extends IGatewayMember>(chatName: string, anonJid: string): G|undefined {
return this.getMembers(chatName).find((user) => user.anonymousJid.toString() === anonJid) as G;
return Array.from(this.getMembers(chatName)).find((user) => user.anonymousJid.toString() === anonJid) as G;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 1% is fine but yeah the inability to iterate on sets is, cough, awful. Almost tempted to use a utility library...

@tadzik tadzik merged commit e1c8d1b into develop Sep 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants