@@ -15,12 +15,8 @@ limitations under the License.
15
15
*/
16
16
17
17
import isIp from "is-ip" ;
18
- import { throttle } from "lodash" ;
19
18
import * as utils from "matrix-js-sdk/src/utils" ;
20
19
import { Room } from "matrix-js-sdk/src/models/room" ;
21
- import { EventType } from "matrix-js-sdk/src/@types/event" ;
22
- import { MatrixEvent } from "matrix-js-sdk/src/models/event" ;
23
- import { RoomMember , RoomMemberEvent } from "matrix-js-sdk/src/models/room-member" ;
24
20
import { logger } from "matrix-js-sdk/src/logger" ;
25
21
import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state" ;
26
22
@@ -108,15 +104,9 @@ export class RoomPermalinkCreator {
108
104
if ( ! this . roomId ) {
109
105
throw new Error ( "Failed to resolve a roomId for the permalink creator to use" ) ;
110
106
}
111
-
112
- if ( shouldThrottle ) {
113
- this . updateServerCandidates = throttle (
114
- this . updateServerCandidates , 200 , { leading : true , trailing : true } ,
115
- ) ;
116
- }
117
107
}
118
108
119
- load ( ) {
109
+ public load ( ) {
120
110
if ( ! this . room || ! this . room . currentState ) {
121
111
// Under rare and unknown circumstances it is possible to have a room with no
122
112
// currentState, at least potentially at the early stages of joining a room.
@@ -125,38 +115,33 @@ export class RoomPermalinkCreator {
125
115
logger . warn ( "Tried to load a permalink creator with no room state" ) ;
126
116
return ;
127
117
}
128
- this . updateAllowedServers ( ) ;
129
- this . updateHighestPlUser ( ) ;
130
- this . updatePopulationMap ( ) ;
131
- this . updateServerCandidates ( ) ;
118
+ this . fullUpdate ( ) ;
132
119
}
133
120
134
- start ( ) {
121
+ public start ( ) {
135
122
this . load ( ) ;
136
- this . room . client . on ( RoomMemberEvent . Membership , this . onMembership ) ;
137
- this . room . currentState . on ( RoomStateEvent . Events , this . onRoomState ) ;
123
+ this . room . currentState . on ( RoomStateEvent . Update , this . onRoomStateUpdate ) ;
138
124
this . started = true ;
139
125
}
140
126
141
- stop ( ) {
142
- this . room . client . removeListener ( RoomMemberEvent . Membership , this . onMembership ) ;
143
- this . room . currentState . removeListener ( RoomStateEvent . Events , this . onRoomState ) ;
127
+ public stop ( ) {
128
+ this . room . currentState . removeListener ( RoomStateEvent . Update , this . onRoomStateUpdate ) ;
144
129
this . started = false ;
145
130
}
146
131
147
- get serverCandidates ( ) {
132
+ public get serverCandidates ( ) {
148
133
return this . _serverCandidates ;
149
134
}
150
135
151
- isStarted ( ) {
136
+ public isStarted ( ) {
152
137
return this . started ;
153
138
}
154
139
155
- forEvent ( eventId : string ) : string {
140
+ public forEvent ( eventId : string ) : string {
156
141
return getPermalinkConstructor ( ) . forEvent ( this . roomId , eventId , this . _serverCandidates ) ;
157
142
}
158
143
159
- forShareableRoom ( ) : string {
144
+ public forShareableRoom ( ) : string {
160
145
if ( this . room ) {
161
146
// Prefer to use canonical alias for permalink if possible
162
147
const alias = this . room . getCanonicalAlias ( ) ;
@@ -167,43 +152,28 @@ export class RoomPermalinkCreator {
167
152
return getPermalinkConstructor ( ) . forRoom ( this . roomId , this . _serverCandidates ) ;
168
153
}
169
154
170
- forRoom ( ) : string {
155
+ public forRoom ( ) : string {
171
156
return getPermalinkConstructor ( ) . forRoom ( this . roomId , this . _serverCandidates ) ;
172
157
}
173
158
174
- private onRoomState = ( event : MatrixEvent ) => {
175
- switch ( event . getType ( ) ) {
176
- case EventType . RoomServerAcl :
177
- this . updateAllowedServers ( ) ;
178
- this . updateHighestPlUser ( ) ;
179
- this . updatePopulationMap ( ) ;
180
- this . updateServerCandidates ( ) ;
181
- return ;
182
- case EventType . RoomPowerLevels :
183
- this . updateHighestPlUser ( ) ;
184
- this . updateServerCandidates ( ) ;
185
- return ;
186
- }
159
+ private onRoomStateUpdate = ( ) => {
160
+ this . fullUpdate ( ) ;
187
161
} ;
188
162
189
- private onMembership = ( evt : MatrixEvent , member : RoomMember , oldMembership : string ) => {
190
- if ( member . roomId !== this . room . roomId ) return ;
191
-
192
- const userId = member . userId ;
193
- const membership = member . membership ;
194
- const serverName = getServerName ( userId ) ;
195
- const hasJoined = oldMembership !== "join" && membership === "join" ;
196
- const hasLeft = oldMembership === "join" && membership !== "join" ;
197
-
198
- if ( hasLeft ) {
199
- this . populationMap [ serverName ] -- ;
200
- } else if ( hasJoined ) {
201
- this . populationMap [ serverName ] ++ ;
202
- }
203
-
163
+ private fullUpdate ( ) {
164
+ // This updates the internal state of this object from the room state. It's broken
165
+ // down into separate functions, previously because we did some of these as incremental
166
+ // updates, but they were on member events which can be very numerous, so the incremental
167
+ // updates ended up being much slower than a full update. We now have the batch state update
168
+ // event, so we just update in full, but on each batch of updates.
169
+ // A full update takes about 120ms for me on Matrix HQ, which still feels like way too long
170
+ // to be spending worrying about how we might generate a permalink, but it's better than
171
+ // multiple seconds.
172
+ this . updateAllowedServers ( ) ;
204
173
this . updateHighestPlUser ( ) ;
174
+ this . updatePopulationMap ( ) ;
205
175
this . updateServerCandidates ( ) ;
206
- } ;
176
+ }
207
177
208
178
private updateHighestPlUser ( ) {
209
179
const plEvent = this . room . currentState . getStateEvents ( "m.room.power_levels" , "" ) ;
0 commit comments