Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: log relay errors only once per app #131

Merged
merged 1 commit into from
Dec 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 31 additions & 20 deletions internal/nostr/nostr.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few lines down (line 726) we cancel the subscription and return if there is an error. I think we should only exit this loop when the context.Done channel receives a message, and we should handle it in one place like we do in Alby Hub.


for {
// context expiration has no effect on relays
Expand All @@ -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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should still log an error here, shouldn't we?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error never happened (in absolute terms), that's why I was confident of it, but doesn't hurt to log, should Ii add it back?

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
}

Expand All @@ -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 {
Expand Down Expand Up @@ -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
Expand All @@ -917,14 +899,43 @@ 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
}
return svc.Relay, false, err
}
}

func (svc *Service) relayConnectWithBackoff(ctx context.Context, relayURL string) (relay *nostr.Relay, err error) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice idea 👍

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 := ""
Expand Down
Loading