timeout relay connections at 2s.

This commit is contained in:
fiatjaf
2026-07-21 18:51:41 -03:00
parent a9df9c6a21
commit aac995714b
5 changed files with 142 additions and 68 deletions
+10 -1
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"strings"
"time"
"fiatjaf.com/nostr"
"fiatjaf.com/nostr/nip45"
@@ -63,12 +64,20 @@ var count = &cli.Command{
hll = hyperloglog.New(offset)
}
for _, relayUrl := range relayUrls {
relay, err := sys.Pool.EnsureRelay(relayUrl)
nm := nostr.NormalizeURL(relayUrl)
relay, ok := sys.Pool.Relays.Load(nm)
if !ok || relay == nil || !relay.IsConnected() {
ct, cancel := context.WithTimeout(context.Background(), 2*time.Second)
var err error
relay, err = nostr.RelayConnect(ct, relayUrl, sys.Pool.RelayOptions)
cancel()
if err != nil {
fmt.Fprintf(os.Stderr, "%s%s: ", strings.Repeat(" ", biggerUrlSize-len(relayUrl)), relayUrl)
fmt.Fprintf(os.Stderr, "error: %s\n", err)
continue
}
sys.Pool.Relays.Store(nm, relay)
}
count, hllRegisters, err := relay.Count(ctx, filter, nostr.SubscriptionOptions{
Label: "nak-count",
+11 -1
View File
@@ -543,11 +543,21 @@ func publishFlow(ctx context.Context, c *cli.Command, kr nostr.Signer, evt nostr
defer cancel()
if !relay.IsConnected() {
if new_, err := sys.Pool.EnsureRelay(relay.URL); err == nil {
nm := nostr.NormalizeURL(relay.URL)
if r, ok := sys.Pool.Relays.Load(nm); ok && r != nil && r.IsConnected() {
relays[i] = r
relay = r
} else {
ct, cancel := context.WithTimeout(context.Background(), 2*time.Second)
new_, err := nostr.RelayConnect(ct, relay.URL, sys.Pool.RelayOptions)
cancel()
if err == nil {
sys.Pool.Relays.Store(nm, new_)
relays[i] = new_
relay = new_
}
}
}
err := relay.Publish(ctx, evt)
if err == nil {
+47 -7
View File
@@ -243,10 +243,18 @@ var group = &cli.Command{
return err
}
r, err := sys.Pool.EnsureRelay(relay)
nm := nostr.NormalizeURL(relay)
r, ok := sys.Pool.Relays.Load(nm)
if !ok || r == nil || !r.IsConnected() {
ct, cancel := context.WithTimeout(context.Background(), 2*time.Second)
var err error
r, err = nostr.RelayConnect(ct, relay, sys.Pool.RelayOptions)
cancel()
if err != nil {
return err
}
sys.Pool.Relays.Store(nm, r)
}
sub, err := r.Subscribe(ctx, nostr.Filter{
Kinds: []nostr.Kind{9},
@@ -316,11 +324,19 @@ var group = &cli.Command{
return fmt.Errorf("failed to sign message: %w", err)
}
if r, err := sys.Pool.EnsureRelay(relay); err != nil {
nm := nostr.NormalizeURL(relay)
r, ok := sys.Pool.Relays.Load(nm)
if !ok || r == nil || !r.IsConnected() {
ct, cancel := context.WithTimeout(context.Background(), 2*time.Second)
var err error
r, err = nostr.RelayConnect(ct, relay, sys.Pool.RelayOptions)
cancel()
if err != nil {
return err
} else {
return r.Publish(ctx, msg)
}
sys.Pool.Relays.Store(nm, r)
}
return r.Publish(ctx, msg)
},
},
},
@@ -474,10 +490,18 @@ write your forum post
return fmt.Errorf("failed to sign forum topic event: %w", err)
}
r, err := sys.Pool.EnsureRelay(relay)
nm := nostr.NormalizeURL(relay)
r, ok := sys.Pool.Relays.Load(nm)
if !ok || r == nil || !r.IsConnected() {
ct, cancel := context.WithTimeout(context.Background(), 2*time.Second)
var err error
r, err = nostr.RelayConnect(ct, relay, sys.Pool.RelayOptions)
cancel()
if err != nil {
return err
}
sys.Pool.Relays.Store(nm, r)
}
return r.Publish(ctx, evt)
},
@@ -581,10 +605,18 @@ write your forum post
return fmt.Errorf("failed to sign forum comment event: %w", err)
}
r, err := sys.Pool.EnsureRelay(relay)
nm := nostr.NormalizeURL(relay)
r, ok := sys.Pool.Relays.Load(nm)
if !ok || r == nil || !r.IsConnected() {
ct, cancel := context.WithTimeout(context.Background(), 2*time.Second)
var err error
r, err = nostr.RelayConnect(ct, relay, sys.Pool.RelayOptions)
cancel()
if err != nil {
return err
}
sys.Pool.Relays.Store(nm, r)
}
return r.Publish(ctx, evt)
},
@@ -906,10 +938,18 @@ func publishModerationEvent(ctx context.Context, c *cli.Command, kind nostr.Kind
stdout(evt.String())
r, err := sys.Pool.EnsureRelay(relay)
nm := nostr.NormalizeURL(relay)
r, ok := sys.Pool.Relays.Load(nm)
if !ok || r == nil || !r.IsConnected() {
ct, cancel := context.WithTimeout(context.Background(), 2*time.Second)
var err error
r, err = nostr.RelayConnect(ct, relay, sys.Pool.RelayOptions)
cancel()
if err != nil {
return err
}
sys.Pool.Relays.Store(nm, r)
}
return r.Publish(ctx, evt)
}
+25 -13
View File
@@ -268,7 +268,31 @@ func connectToSingleRelay(
colorizepreamble func(c func(string, ...any) string),
logthis func(s string, args ...any),
) *nostr.Relay {
if relay, err := sys.Pool.EnsureRelay(url); err == nil {
nm := nostr.NormalizeURL(url)
relay, ok := sys.Pool.Relays.Load(nm)
if !ok || relay == nil || !relay.IsConnected() {
connectCtx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
var err error
if relay, err = nostr.RelayConnect(connectCtx, url, sys.Pool.RelayOptions); err != nil {
if colorizepreamble != nil {
colorizepreamble(colors.errorf)
}
logthis(clampError(err, len(url)+12))
return nil
}
sys.Pool.Relays.Store(nm, relay)
go func(r *nostr.Relay, relayURL string) {
<-r.Context().Done()
if current, ok := sys.Pool.Relays.Load(relayURL); ok && current == r {
sys.Pool.Relays.Delete(relayURL)
}
}(relay, nm)
}
if c.Bool("force-pre-auth") {
if colorizepreamble != nil {
colorizepreamble(color.YellowString)
@@ -289,11 +313,9 @@ func connectToSingleRelay(
} else {
// auth failed
if strings.HasSuffix(err.Error(), "auth not received yet *****") {
// it failed because we didn't receive the challenge yet, so keep waiting
time.Sleep(time.Second)
continue
} else {
// it failed for some other reason, so skip this relay
if colorizepreamble != nil {
colorizepreamble(colors.errorf)
}
@@ -315,16 +337,6 @@ func connectToSingleRelay(
}
logthis("ok.")
return relay
} else {
if colorizepreamble != nil {
colorizepreamble(colors.errorf)
}
// if we're here that means we've failed to connect, this may be a huge message
// but we're likely to only be interested in the lowest level error (although we can leave space)
logthis(clampError(err, len(url)+12))
return nil
}
}
func clearLines(lineCount int) {
+4 -1
View File
@@ -996,10 +996,13 @@ func (r *NostrRoot) publishNote(path string) {
}
for _, url := range relays {
relay, err := r.sys.Pool.EnsureRelay(url)
connectCtx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
relay, err := nostr.RelayConnect(connectCtx, url, r.sys.Pool.RelayOptions)
cancel()
if err != nil {
continue
}
r.sys.Pool.Relays.Store(nostr.NormalizeURL(url), relay)
relay.Publish(ctx, *evt)
}