From 5930f6e8177e51eb2bda80da61e64f548a6e972f Mon Sep 17 00:00:00 2001 From: im-adithya Date: Fri, 20 Dec 2024 01:17:27 +0530 Subject: [PATCH] chore: log relay errors only once per app --- internal/nostr/nostr.go | 51 +++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/internal/nostr/nostr.go b/internal/nostr/nostr.go index 944ff01..e5957c9 100644 --- a/internal/nostr/nostr.go +++ b/internal/nostr/nostr.go @@ -713,7 +713,6 @@ func (svc *Service) startSubscription(ctx context.Context, subscription *Subscri var relay *nostr.Relay var isCustomRelay bool var err error - waitToReconnectSeconds := 0 for { // context expiration has no effect on relays @@ -728,28 +727,13 @@ func (svc *Service) startSubscription(ctx context.Context, subscription *Subscri svc.stopSubscription(subscription) return } - time.Sleep(time.Duration(waitToReconnectSeconds) * time.Second) relay, isCustomRelay, err = svc.getRelayConnection(ctx, subscription.RelayUrl) if err != nil { - // TODO: notify user about relay failure - waitToReconnectSeconds = max(waitToReconnectSeconds, 1) - waitToReconnectSeconds = min(waitToReconnectSeconds * 2, 900) - svc.Logger.WithError(err).WithFields(logrus.Fields{ - "subscription_id": subscription.Uuid, - "relay_url": subscription.RelayUrl, - }).Errorf("Failed to connect to relay, retrying in %vs...", waitToReconnectSeconds) continue } sub, err := relay.Subscribe(ctx, []nostr.Filter{*filter}) if err != nil { - // TODO: notify user about subscription failure - waitToReconnectSeconds = max(waitToReconnectSeconds, 1) - waitToReconnectSeconds = min(waitToReconnectSeconds * 2, 900) - svc.Logger.WithError(err).WithFields(logrus.Fields{ - "subscription_id": subscription.Uuid, - "relay_url": subscription.RelayUrl, - }).Errorf("Failed to subscribe to relay, retrying in %vs...", waitToReconnectSeconds) continue } @@ -762,8 +746,6 @@ func (svc *Service) startSubscription(ctx context.Context, subscription *Subscri "relay_url": subscription.RelayUrl, }).Debug("Started subscription") - waitToReconnectSeconds = 0 - err = svc.processEvents(ctx, subscription, onReceiveEOS, handleEvent) if err != nil { @@ -906,7 +888,7 @@ func (svc *Service) getRelayConnection(ctx context.Context, customRelayURL strin svc.Logger.WithFields(logrus.Fields{ "custom_relay_url": customRelayURL, }).Info("Connecting to custom relay") - relay, err := nostr.RelayConnect(ctx, customRelayURL) + relay, err := svc.relayConnectWithBackoff(ctx, customRelayURL) return relay, true, err // true means custom and the relay should be closed } // use mutex otherwise the svc.Relay will be reconnected more than once @@ -917,7 +899,7 @@ func (svc *Service) getRelayConnection(ctx context.Context, customRelayURL strin return svc.Relay, false, nil } else { svc.Logger.Info("Lost connection to default relay, reconnecting...") - relay, err := nostr.RelayConnect(svc.Ctx, svc.Cfg.DefaultRelayURL) + relay, err := svc.relayConnectWithBackoff(svc.Ctx, svc.Cfg.DefaultRelayURL) if err == nil { svc.Relay = relay } @@ -925,6 +907,35 @@ func (svc *Service) getRelayConnection(ctx context.Context, customRelayURL strin } } +func (svc *Service) relayConnectWithBackoff(ctx context.Context, relayURL string) (relay *nostr.Relay, err error) { + waitToReconnectSeconds := 0 + for { + select { + case <-ctx.Done(): + svc.Logger.WithError(err).WithFields(logrus.Fields{ + "relay_url": relayURL, + }).Errorf("Context canceled, exiting attempt to connect to relay") + return nil, ctx.Err() + default: + time.Sleep(time.Duration(waitToReconnectSeconds) * time.Second) + relay, err = nostr.RelayConnect(ctx, relayURL) + if err != nil { + // TODO: notify user about relay failure + waitToReconnectSeconds = max(waitToReconnectSeconds, 1) + waitToReconnectSeconds = min(waitToReconnectSeconds * 2, 900) + svc.Logger.WithError(err).WithFields(logrus.Fields{ + "relay_url": relayURL, + }).Errorf("Failed to connect to relay, retrying in %vs...", waitToReconnectSeconds) + continue + } + svc.Logger.WithFields(logrus.Fields{ + "relay_url": relayURL, + }).Info("Relay connection successful.") + return relay, nil + } + } +} + func (svc *Service) postEventToWebhook(event *nostr.Event, subscription *Subscription) { eventData, err := json.Marshal(event) request_event_id := ""