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 <p>Below, we have inserted a <code>script</code> tag that should
renter a Svelte component upon loading this page.</p> renter a Svelte component upon loading this page.</p>
<script <script src="public/bundle.js"
src="public/bundle.js"
data-chat-type="GLOBAL" data-chat-type="GLOBAL"
data-chat-tags="nostrica" data-chat-tags="nostrica,nostrica2023"
data-relays="ws://localhost:8080" 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> ></script>
<link rel="stylesheet" href="public/bundle.css">
></script>
<p>This text will come after the embedded content.</p> <p>This text will come after the embedded content.</p>
</body> </body>

View file

@ -91,11 +91,16 @@
isThread = new Set(pubkeysTagged).size >= 2; isThread = new Set(pubkeysTagged).size >= 2;
} }
responses[message.id] = []; if (!responses[message.id]) { responses[message.id] = [] };
if (isThread) { if (isThread) {
// get the last "e" tag, which is tagging the immediate parent
const lastETag = message.tags.filter(tag => tag[0] === 'e').pop(); 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); responses[lastETag[1]].push(message);
} }

View file

@ -1,6 +1,8 @@
<script> <script>
import { onMount } from 'svelte';
import { selectedMessage } from './lib/store'; 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 event;
export let responses; export let responses;
export let websiteOwnerPubkey; 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; const byWebsiteOwner = !!websiteOwnerPubkey === event.pubkey;
$: profiles = $chatData.profiles; $: profiles = $chatData.profiles;
$: displayName = profiles[event.pubkey] && profiles[event.pubkey].display_name || `[${event.pubkey.slice(0, 6)}]`; $: displayName = profiles[event.pubkey] && profiles[event.pubkey].display_name || `[${event.pubkey.slice(0, 6)}]`;
$: nip05 = profiles[event.pubkey] && profiles[event.pubkey].nip05; $: 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]); const repliedIds = event.tags.filter(e => e[0] === 'e').map(e => e[1]);

View file

@ -25,6 +25,8 @@ class NstrAdapter {
#profileRequestQueue = []; #profileRequestQueue = [];
#requestedProfiles = []; #requestedProfiles = [];
#profileRequestTimer; #profileRequestTimer;
#delayedSubscriptions = {};
#delayedSubscriptionTimeouts = {};
constructor(clientPubkey, {tags, referenceTags, type='DM', websiteOwnerPubkey, relays} = {}) { constructor(clientPubkey, {tags, referenceTags, type='DM', websiteOwnerPubkey, relays} = {}) {
this.pubkey = clientPubkey; this.pubkey = clientPubkey;
@ -72,8 +74,6 @@ class NstrAdapter {
break; break;
} }
console.log('filters', filters);
if (filters && filters.length > 0) { if (filters && filters.length > 0) {
this.subscribe(filters, (e) => { this.#emitMessage(e) }) this.subscribe(filters, (e) => { this.#emitMessage(e) })
} }
@ -170,6 +170,21 @@ class NstrAdapter {
messageCallback(event) 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) { async subscribe(filters, messageCallback=null) {
if (!messageCallback) { messageCallback = (e) => { this.#emitMessage(e) } } if (!messageCallback) { messageCallback = (e) => { this.#emitMessage(e) } }
return this.#_subscribe(filters, messageCallback) return this.#_subscribe(filters, messageCallback)
@ -200,14 +215,6 @@ class NstrAdapter {
event.content = await this.decrypt(this.#websiteOwnerPubkey, event.content); 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.kind === 1) {
if (!event.tags.find(t => t[0] === 'e')) { if (!event.tags.find(t => t[0] === 'e')) {
// a top level message that we should subscribe to since responses won't tag the url // a top level message that we should subscribe to since responses won't tag the url

View file

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