Skip to content

Commit

Permalink
If we get a presence flood, fetch each caps once
Browse files Browse the repository at this point in the history
Since the query may still be in flight, we won't see the result in the
DB, but we still don't want to send out another query for the same caps
hash right now.
  • Loading branch information
singpolyma committed Jun 27, 2024
1 parent 16ce799 commit 1b7a81e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 10 deletions.
37 changes: 27 additions & 10 deletions snikket/Client.hx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class Client extends EventEmitter {
);
private var _displayName: String;
private var fastMechanism: Null<String> = null;
private final pendingCaps: Map<String, Array<(Null<Caps>)->Chat>> = [];

/**
Create a new Client to connect to a particular account
Expand Down Expand Up @@ -342,20 +343,36 @@ class Client extends EventEmitter {
persistence.storeChat(accountId(), chat);
if (chat.livePresence()) this.trigger("chats/update", [chat]);
} else {
final handleCaps = (caps) -> {
chat.setPresence(JID.parse(stanza.attr.get("from")).resource, new Presence(caps, mucUser));
persistence.storeChat(accountId(), chat);
return chat;
};

persistence.getCaps(c.attr.get("ver"), (caps) -> {
if (caps == null) {
final discoGet = new DiscoInfoGet(stanza.attr.get("from"), c.attr.get("node") + "#" + c.attr.get("ver"));
discoGet.onFinished(() -> {
chat.setPresence(JID.parse(stanza.attr.get("from")).resource, new Presence(discoGet.getResult(), mucUser));
if (discoGet.getResult() != null) persistence.storeCaps(discoGet.getResult());
persistence.storeChat(accountId(), chat);
final pending = pendingCaps.get(c.attr.get("ver"));
if (pending == null) {
pendingCaps.set(c.attr.get("ver"), [handleCaps]);
final discoGet = new DiscoInfoGet(stanza.attr.get("from"), c.attr.get("node") + "#" + c.attr.get("ver"));
discoGet.onFinished(() -> {
final chatsToUpdate: Map<String, Chat> = [];
final handlers = pendingCaps.get(c.attr.get("ver")) ?? [];
pendingCaps.remove(c.attr.get("ver"));
if (discoGet.getResult() != null) persistence.storeCaps(discoGet.getResult());
for (handler in handlers) {
final c = handler(discoGet.getResult());
if (c.livePresence()) chatsToUpdate.set(c.chatId, c);
}
this.trigger("chats/update", Lambda.array({ iterator: () -> chatsToUpdate.iterator() }));
});
sendQuery(discoGet);
} else {
pending.push(handleCaps);
if (chat.livePresence()) this.trigger("chats/update", [chat]);
});
sendQuery(discoGet);
}
} else {
chat.setPresence(JID.parse(stanza.attr.get("from")).resource, new Presence(caps, mucUser));
persistence.storeChat(accountId(), chat);
if (chat.livePresence()) this.trigger("chats/update", [chat]);
handleCaps(caps);
}
});
}
Expand Down
4 changes: 4 additions & 0 deletions snikket/Map.js.hx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ abstract Map<K,V>(NativeMap<K,V>) {
this.set(k, v);
}

public inline function get(k:K):Null<V> {
return this.get(k);
}

public inline function exists(k:K):Bool {
return this.has(k);
}
Expand Down

0 comments on commit 1b7a81e

Please sign in to comment.