When writing Nostr clients, working with relays are \"challenging\" to say the least. There is little information stating exactly how it \"should\" be done. A lot of relays are misbehaving, or at least are punishing people messing up their own clients. Relays might accept connections, but not react to anything. Or they might react but with usage limits (connections and/or a limit on the number of simultaneous pending requests).

When a traditional (\"X style\") Nostr client starts up, there is a lot of things to be done. You need to fetch user metadata on the currently logged in user, including some profile data, followers list, relay list and similar.

Then you need to connect to the relays and ask for historical posts (nobody wants a blank feed). So you connect to each relay in the user relay list and they will throw events at your like there is no tomorrow. At least the ones that bother to reply.

So now you have lots of events. Guess what you now need to do? For each one of these, you need to get the user metadata for the poster (people want to see who is posting). If it's a repost, you might want to fetch the original post as well (there's a couple of different ways Nostr handles this). And if it's a reply, you might want to show that it is a reply (and to which user and which post). Yeah, more requests to relays.

So with your recently populated list of historical posts, you know have lots of queries to the relays to fill in the missing pieces for each post (at least for reposts and replies). So you start hitting the relays again.

So this is where you need a relay connection pool manager. You want to avoid reconnecting to all the relays for each query/subscription, because this takes time, and relays do not appreciate you eating all their sockets. Fine, just send them over the same connection then. Well, the relays don't like too many pending requests/subscriptions either. So if you hit some magical number - typically 10 - the relays will start rate limiting you, and not accepting new queries. And keep in mind relays might have different \"politics\" on how to handle this.

For my own client - Pumpstr - I initially tried to use the pool manager that comes with nostr-utils. It's a great resource, but the pool manager does not really work for clients. It works great as a starting point to learn about Nostr, but you can not rely on this when writing a \"full\" Nostr client. It's just too primitive. It really does not have the concept of \"subscriptions\" versus \"relay connections\", and when closing a subscription it will typically also kill your relay connections. Good like trying to writing a well behaved Nostr client with that.

So I rabbit holed this deeply (as usual), and rewrote my own Nostr connection pool manager. It now tracks the number of pending queries/subscriptions on a per relay basis, and connections are independent from subscriptions. When a relay disconnects you - they will periodically - it also automatically resubscribes to existing subscriptions.

It might not be perfect just yet, but it is getting pretty damned close!

Reply to this note

Please Login to reply.

Discussion

Posting and "quotes" works fine. The misquoted quotes is because I had to rescue the original post from a browser log after it failed the first time. And that quoted them which I forgot to clean up before trying to post again.