add a lazyload for large rooms

This commit is contained in:
emerson 2022-02-18 17:07:51 -05:00
parent 5124e98a49
commit 06b2d86017
5 changed files with 26 additions and 15 deletions

View file

@ -29,9 +29,6 @@ You can't send a PM to individual users, since a "PM" in Matrix is just another
### Spaces
There's no IRC equivalent to Spaces (I'll probably write a spec for it since it's widely used elsewhere). Since they are just regular rooms, they show up in IRC as just regular rooms. You aren't supposed to send messages to them, once I implement mode handling I'll use `+m` to disallow sending.
### Client overload
If you're in a ton of channels, or several big ones, your IRC client/CPU might melt slightly on initial sync. I'm working on a "lazy-loading" channel list to fix that. Joining `#matrix:matrix.org` using WeeChat pegs a CPU core for a good 45 seconds.
### Highlighting users
In order to highlight users, you need to prefix their nick with an `@`, so `@emerson: hi`. Reflection automatically expands this to the user's MXID, so even though it's annoying, it's needed to stop inadvertent highlights for now.

View file

@ -2,5 +2,6 @@
"serverName": "testing.",
"port": 6697,
"certFile": "reflection.pem",
"keyFile": "reflection.key"
"keyFile": "reflection.key",
"lazyLoadLimit": 500
}

View file

@ -9,6 +9,7 @@ export class Channel {
// <nick, PL number>
public powerLevels: Map<string, number>
public topic: Map<string, string>;
public channelModes: Map<string, string>;
public eventIDsSeen: Set<string>;
public historyVisibility: string
public guestAccess: string
@ -21,11 +22,13 @@ export class Channel {
this.matrixUsers.set(initialMatrixUser.nick, initialMatrixUser);
this.powerLevels = new Map();
this.topic = new Map([['text', ''], ['timestamp', '0'], ['setter', 'matrix']]);
this.channelModes = new Map([['n', '']]);
this.eventIDsSeen = new Set();
this.historyVisibility = "";
this.guestAccess = "";
this.joinRules = "";
this.syncLocks = new Set();
this.syncLocks.add('isDM');
this.doInitialSync();
this.initialSyncID = setInterval(this.checkChannelSync.bind(this), 2000);
}
@ -66,10 +69,15 @@ export class Channel {
this.syncLocks.add("m.room.members");
axios.get(`https://${this.ircUser.homeserver}/_matrix/client/v3/rooms/${this.roomId}/joined_members?access_token=${this.ircUser.accessToken}`).then(response => {
const allMembers = response.data["joined"];
for (const member of Object.keys(allMembers)) {
const allMxids = Object.keys(allMembers);
if (allMxids.length > this.ircUser.server.config["lazyLoadLimit"]) {
this.channelModes.set('u', '');
} else {
for (const member of allMxids) {
const nextMatrixUser = this.ircUser.getOrCreateMatrixUser(member);
this.matrixUsers.set(nextMatrixUser.nick, nextMatrixUser);
}
}
this.syncLocks.delete("m.room.members")
}).catch(e => {
const errcode = e.response?.data?.errcode;
@ -99,13 +107,14 @@ export class Channel {
}
checkChannelSync() {
if (this.isSynced()) {
if (this.syncLocks.size === 1) {
if (this.matrixUsers.size === 2 && this.name === this.roomId) {
const otherUser = [...this.matrixUsers.values()].filter(m => m.nick !== this.ircUser.nick);
const directRoomsForUser = this.ircUser.directRooms.get(otherUser[0].mxid);
if (directRoomsForUser && directRoomsForUser.includes(this.roomId))
this.name = `&${otherUser[0].mxid.substring(1)}`
}
this.syncLocks.delete('isDM');
this.ircUser.finishChannelSync(this);
clearInterval(this.initialSyncID);
}

View file

@ -202,7 +202,10 @@ export class Client {
for (const roomId of Object.keys(rooms.join)) {
const targetChannel = this.user.getOrCreateIRCChannel(roomId);
//@ts-ignore
rooms.join[roomId].state.events.forEach((nextEvent: any) => this.user.routeMatrixEvent(nextEvent, targetChannel));
rooms.join[roomId].state.events.forEach((nextEvent: any) => {
if (targetChannel.isSynced() && this.user)
this.user.routeMatrixEvent(nextEvent, targetChannel)
});
}
}
if (this.user === null)
@ -351,7 +354,8 @@ export class Client {
}
if (!this.checkIfInChannel(targetChannel)) return;
if (message.params.length === 1) {
this.sendMessage(this.server.name, "324", [this.user.nick, targetChannel.name, `+n`]);
const chanModes = [...targetChannel.channelModes.keys()].sort().join('');
this.sendMessage(this.server.name, "324", [this.user.nick, targetChannel.name, `+${chanModes}`]);
return;
}
}
@ -569,10 +573,10 @@ export class Client {
this.sendMessage(this.server.name, '001', numerics['001'](this.user.nick, this.server.name));
this.sendMessage(this.server.name, '002', numerics['002'](this.user.nick, this.server.name, '0.0.1'));
this.sendMessage(this.server.name, '003', numerics['003'](this.user.nick, 'yesterday'));
this.sendMessage(this.server.name, '004', numerics['004'](this.user.nick, this.server.name, '0.0.1', 'i', 'Lhionpsv'));
this.sendMessage(this.server.name, '004', numerics['004'](this.user.nick, this.server.name, '0.0.1', 'i', 'hnovu'));
const iSupportArray = [
'CASEMAPPING=ascii',
'CHANMODES=,,,Linps',
'CHANMODES=,,,nu',
'CHANTYPES=#&!',
'MAXTARGETS=1',
'PREFIX=(ohv)@%+',

View file

@ -24,7 +24,7 @@ export class IRCUser {
private isSyncing: boolean
private currentSyncTime: number
private syncIntervalID: NodeJS.Timeout;
constructor(public mxid: string, public accessToken: string, public homeserver: string, private server: Server) {
constructor(public mxid: string, public accessToken: string, public homeserver: string, public server: Server) {
this.clients = new Set();
this.channels = new Map();
this.roomIdToChannel = new Map();
@ -251,7 +251,7 @@ export class IRCUser {
case 'org.matrix.msc3381.poll.start':
break;
default:
console.log(nextEvent);
console.log(`${targetChannel.name}: ${nextEvent}`);
break;
}
}