Skip to content

Commit

Permalink
Retain relays from purple pages in case further lookups fail
Browse files Browse the repository at this point in the history
  • Loading branch information
boreq committed Nov 1, 2023
1 parent cd8f85d commit ea562e8
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 6 deletions.
72 changes: 67 additions & 5 deletions service/adapters/relay_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ package adapters

import (
"context"
"sync"
"time"

"github.com/boreq/errors"
"github.com/planetary-social/nos-crossposting-service/internal"
"github.com/planetary-social/nos-crossposting-service/internal/logging"
"github.com/planetary-social/nos-crossposting-service/service/domain"
)

const refreshPurplePagesAfter = 30 * time.Minute

var hardcodedRelayAddresses = []domain.RelayAddress{
domain.MustNewRelayAddress("wss://relay.damus.io"),
domain.MustNewRelayAddress("wss://nos.lol"),
Expand All @@ -18,10 +22,15 @@ var hardcodedRelayAddresses = []domain.RelayAddress{
type RelaySource struct {
logger logging.Logger
purplePages *PurplePages
cache *RelayAddressCache
}

func NewRelaySource(logger logging.Logger, purplePages *PurplePages) *RelaySource {
return &RelaySource{logger: logger, purplePages: purplePages}
return &RelaySource{
logger: logger,
purplePages: purplePages,
cache: NewRelayAddressCache(),
}
}

func (p RelaySource) GetRelays(ctx context.Context, publicKey domain.PublicKey) ([]domain.RelayAddress, error) {
Expand All @@ -31,18 +40,71 @@ func (p RelaySource) GetRelays(ctx context.Context, publicKey domain.PublicKey)
result.Put(relayAddress)
}

relayAddressesFromPurplePages, err := p.getRelaysFromPurplePages(ctx, publicKey)
if err != nil {
return nil, errors.Wrap(err, "error getting relays from purple pages")
}

for _, relayAddress := range relayAddressesFromPurplePages {
result.Put(relayAddress)
}

return result.List(), nil
}

func (p RelaySource) getRelaysFromPurplePages(ctx context.Context, publicKey domain.PublicKey) ([]domain.RelayAddress, error) {
var previousEntries []domain.RelayAddress

entry, ok := p.cache.Get(publicKey)
if ok {
previousEntries = entry.Addresses
if time.Since(entry.T) < refreshPurplePagesAfter {
return previousEntries, nil
}
}

relayAddressesFromPurplePages, err := p.purplePages.GetRelays(ctx, publicKey)
if err != nil {
if errors.Is(err, ErrRelayListNotFoundInPurplePages) ||
errors.Is(err, ErrPurplePagesTimeout) {
return result.List(), nil
return previousEntries, nil
}
return nil, errors.Wrap(err, "error querying purple pages")
}

for _, relayAddress := range relayAddressesFromPurplePages {
result.Put(relayAddress)
p.cache.Set(publicKey, relayAddressesFromPurplePages)

return relayAddressesFromPurplePages, nil
}

type RelayAddressCache struct {
m map[domain.PublicKey]Entry
lock sync.Mutex
}

func NewRelayAddressCache() *RelayAddressCache {
return &RelayAddressCache{m: make(map[domain.PublicKey]Entry)}
}

func (c *RelayAddressCache) Set(publicKey domain.PublicKey, addresses []domain.RelayAddress) {
c.lock.Lock()
defer c.lock.Unlock()

c.m[publicKey] = Entry{
T: time.Now(),
Addresses: addresses,
}
}

return result.List(), nil
func (c *RelayAddressCache) Get(publicKey domain.PublicKey) (Entry, bool) {
c.lock.Lock()
defer c.lock.Unlock()

v, ok := c.m[publicKey]
return v, ok
}

type Entry struct {
T time.Time
Addresses []domain.RelayAddress
}
2 changes: 1 addition & 1 deletion service/app/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const (
howFarIntoThePastToLook = 24 * time.Hour
storeMetricsEvery = 30 * time.Second
refreshDownloaderPublicKeysEvery = 1 * time.Minute
refreshPublicKeyDownloaderRelaysEvery = 60 * time.Minute
refreshPublicKeyDownloaderRelaysEvery = 1 * time.Minute
)

type ReceivedEventPublisher interface {
Expand Down

0 comments on commit ea562e8

Please sign in to comment.