Something went wrong. Try again.
Monorepo for Tangled
Something went wrong. Try again.
3.0 kB · 125 lines
Go
at ci
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126package idresolver
import ( "context" "net" "net/http" "sync" "time"
"github.com/bluesky-social/indigo/atproto/identity" "github.com/bluesky-social/indigo/atproto/identity/redisdir" "github.com/bluesky-social/indigo/atproto/syntax" "github.com/carlmjohnson/versioninfo")
type Resolver struct { directory identity.Directory}
func BaseDirectory(plcUrl string) identity.Directory { base := identity.BaseDirectory{ PLCURL: plcUrl, HTTPClient: http.Client{ Timeout: time.Second * 10, Transport: &http.Transport{ // would want this around 100ms for services doing lots of handle resolution. Impacts PLC connections as well, but not too bad. IdleConnTimeout: time.Millisecond * 1000, MaxIdleConns: 100, }, }, Resolver: net.Resolver{ Dial: func(ctx context.Context, network, address string) (net.Conn, error) { d := net.Dialer{Timeout: time.Second * 3} return d.DialContext(ctx, network, address) }, }, TryAuthoritativeDNS: true, // primary Bluesky PDS instance only supports HTTP resolution method SkipDNSDomainSuffixes: []string{".bsky.social"}, UserAgent: "indigo-identity/" + versioninfo.Short(), } return &base}
func RedisDirectory(url, plcUrl string) (identity.Directory, error) { hitTTL := time.Hour * 24 errTTL := time.Second * 30 invalidHandleTTL := time.Minute * 5 return redisdir.NewRedisDirectory( BaseDirectory(plcUrl), url, hitTTL, errTTL, invalidHandleTTL, 10000, )}
func DefaultResolver(plcUrl string) *Resolver { base := BaseDirectory(plcUrl) cached := identity.NewCacheDirectory(base, 250_000, time.Hour*24, time.Minute*2, time.Minute*5) return &Resolver{ directory: &cached, }}
func RedisResolver(redisUrl, plcUrl string) (*Resolver, error) { directory, err := RedisDirectory(redisUrl, plcUrl) if err != nil { return nil, err } return &Resolver{ directory: directory, }, nil}
func (r *Resolver) ResolveIdent(ctx context.Context, arg string) (*identity.Identity, error) { id, err := syntax.ParseAtIdentifier(arg) if err != nil { return nil, err }
return r.directory.Lookup(ctx, *id)}
func (r *Resolver) ResolveIdents(ctx context.Context, idents []string) []*identity.Identity { results := make([]*identity.Identity, len(idents)) var wg sync.WaitGroup
done := make(chan struct{}) defer close(done)
for idx, ident := range idents { wg.Add(1) go func(index int, id string) { defer wg.Done()
select { case <-ctx.Done(): results[index] = nil case <-done: results[index] = nil default: identity, _ := r.ResolveIdent(ctx, id) results[index] = identity } }(idx, ident) }
wg.Wait() return results}
func (r *Resolver) InvalidateIdent(ctx context.Context, arg string) error { id, err := syntax.ParseAtIdentifier(arg) if err != nil { return err }
return r.directory.Purge(ctx, *id)}
func (r *Resolver) Directory() identity.Directory { return r.directory}