buffer subsequent requests to avoid hammering relays

This commit is contained in:
pablof7z 2023-03-16 16:58:16 +01:00
parent 6b831c62c7
commit d8ac846fae
5 changed files with 40 additions and 23 deletions

View file

@ -11,15 +11,11 @@
<p>Below, we have inserted a <code>script</code> tag that should
renter a Svelte component upon loading this page.</p>
<script
src="public/bundle.js"
<script src="public/bundle.js"
data-chat-type="GLOBAL"
data-chat-tags="nostrica"
data-relays="ws://localhost:8080"
data-chat-tags="nostrica,nostrica2023"
data-relays="wss://relay.nostrica.com,wss://relay.f7z.io,wss://nos.lol,wss://relay.nostr.info,wss://nostr-pub.wellorder.net,wss://relay.current.fyi,wss://relay.nostr.band"
></script>
<link rel="stylesheet" href="public/bundle.css">
></script>
<p>This text will come after the embedded content.</p>
</body>

View file

@ -91,11 +91,16 @@
isThread = new Set(pubkeysTagged).size >= 2;
}
responses[message.id] = [];
if (!responses[message.id]) { responses[message.id] = [] };
if (isThread) {
// get the last "e" tag, which is tagging the immediate parent
const lastETag = message.tags.filter(tag => tag[0] === 'e').pop();
if (lastETag && lastETag[1] && responses[lastETag[1]]) {
if (lastETag && lastETag[1]) {
// if there is one, add it to the response
if (!responses[lastETag[1]]) {
responses[lastETag[1]] = [];
}
responses[lastETag[1]].push(message);
}

View file

@ -1,6 +1,8 @@
<script>
import { onMount } from 'svelte';
import { selectedMessage } from './lib/store';
import { chatData } from './lib/store';
import { chatData, chatAdapter } from './lib/store';
// import { prettifyContent } from '$lib/utils';
export let event;
export let responses;
export let websiteOwnerPubkey;
@ -16,13 +18,20 @@
}
}
// delay-fetch responses
onMount(() => {
$chatAdapter.delayedSubscribe(
{kinds: [1], '#e': [event.id]}
, 'responses', 500)
})
const byWebsiteOwner = !!websiteOwnerPubkey === event.pubkey;
$: profiles = $chatData.profiles;
$: displayName = profiles[event.pubkey] && profiles[event.pubkey].display_name || `[${event.pubkey.slice(0, 6)}]`;
$: nip05 = profiles[event.pubkey] && profiles[event.pubkey].nip05;
$: profilePicture = profiles[event.pubkey] && profiles[event.pubkey].picture || `https://robohash.org/${event.pubkey}.png?set=set1`;
$: profilePicture = profiles[event.pubkey] && profiles[event.pubkey].picture || `https://robohash.org/${event.pubkey.slice(0, 2)}.png?set=set1`;
const repliedIds = event.tags.filter(e => e[0] === 'e').map(e => e[1]);

View file

@ -25,6 +25,8 @@ class NstrAdapter {
#profileRequestQueue = [];
#requestedProfiles = [];
#profileRequestTimer;
#delayedSubscriptions = {};
#delayedSubscriptionTimeouts = {};
constructor(clientPubkey, {tags, referenceTags, type='DM', websiteOwnerPubkey, relays} = {}) {
this.pubkey = clientPubkey;
@ -72,8 +74,6 @@ class NstrAdapter {
break;
}
console.log('filters', filters);
if (filters && filters.length > 0) {
this.subscribe(filters, (e) => { this.#emitMessage(e) })
}
@ -170,6 +170,21 @@ class NstrAdapter {
messageCallback(event)
}
async delayedSubscribe(filters, family, timeout) {
this.#delayedSubscriptions[family] = this.#delayedSubscriptions[family] || []
this.#delayedSubscriptions[family].push(filters);
if (!this.#delayedSubscriptionTimeouts[family]) {
this.#delayedSubscriptionTimeouts[family] = setTimeout(() => {
delete this.#delayedSubscriptionTimeouts[family];
filters = this.#delayedSubscriptions[family];
delete this.#delayedSubscriptions[family];
this.subscribe(filters, (e) => { this.#emitMessage(e)});
}, timeout)
}
}
async subscribe(filters, messageCallback=null) {
if (!messageCallback) { messageCallback = (e) => { this.#emitMessage(e) } }
return this.#_subscribe(filters, messageCallback)
@ -200,14 +215,6 @@ class NstrAdapter {
event.content = await this.decrypt(this.#websiteOwnerPubkey, event.content);
}
// if we have tags we were filtering for, filter here in case the relay doesn't support filtering
if (this.tags && this.tags.length > 0) {
if (!event.tags.find(t => t[0] === 't' && this.tags.includes(t[1]))) {
console.log(`discarded event not tagged with [${this.tags.join(', ')}], tags: ${event.tags.filter(t => t[0] === 't').map(t => t[1]).join(', ')}`);
return;
}
}
if (event.kind === 1) {
if (!event.tags.find(t => t[0] === 'e')) {
// a top level message that we should subscribe to since responses won't tag the url

View file

@ -88,7 +88,7 @@
chatType,
chatTags,
chatReferenceTags,
}} {websiteOwnerPubkey} {relays} bind:chatStarted={chatStarted} />
}} {relays} bind:chatStarted={chatStarted} />
</div>
</div>
</div>