forked from tangled.org/core
this repo has no description
1package idresolver 2 3import ( 4 "context" 5 "net" 6 "net/http" 7 "sync" 8 "time" 9 10 "github.com/bluesky-social/indigo/atproto/identity" 11 "github.com/bluesky-social/indigo/atproto/identity/redisdir" 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 "github.com/carlmjohnson/versioninfo" 14 "tangled.sh/tangled.sh/core/appview/config" 15) 16 17type Resolver struct { 18 directory identity.Directory 19} 20 21func BaseDirectory() identity.Directory { 22 base := identity.BaseDirectory{ 23 PLCURL: identity.DefaultPLCURL, 24 HTTPClient: http.Client{ 25 Timeout: time.Second * 10, 26 Transport: &http.Transport{ 27 // would want this around 100ms for services doing lots of handle resolution. Impacts PLC connections as well, but not too bad. 28 IdleConnTimeout: time.Millisecond * 1000, 29 MaxIdleConns: 100, 30 }, 31 }, 32 Resolver: net.Resolver{ 33 Dial: func(ctx context.Context, network, address string) (net.Conn, error) { 34 d := net.Dialer{Timeout: time.Second * 3} 35 return d.DialContext(ctx, network, address) 36 }, 37 }, 38 TryAuthoritativeDNS: true, 39 // primary Bluesky PDS instance only supports HTTP resolution method 40 SkipDNSDomainSuffixes: []string{".bsky.social"}, 41 UserAgent: "indigo-identity/" + versioninfo.Short(), 42 } 43 return &base 44} 45 46func RedisDirectory(url string) (identity.Directory, error) { 47 hitTTL := time.Hour * 24 48 errTTL := time.Second * 30 49 invalidHandleTTL := time.Minute * 5 50 return redisdir.NewRedisDirectory(BaseDirectory(), url, hitTTL, errTTL, invalidHandleTTL, 10000) 51} 52 53func DefaultResolver() *Resolver { 54 return &Resolver{ 55 directory: identity.DefaultDirectory(), 56 } 57} 58 59func RedisResolver(config config.RedisConfig) (*Resolver, error) { 60 directory, err := RedisDirectory(config.ToURL()) 61 if err != nil { 62 return nil, err 63 } 64 return &Resolver{ 65 directory: directory, 66 }, nil 67} 68 69func (r *Resolver) ResolveIdent(ctx context.Context, arg string) (*identity.Identity, error) { 70 id, err := syntax.ParseAtIdentifier(arg) 71 if err != nil { 72 return nil, err 73 } 74 75 return r.directory.Lookup(ctx, *id) 76} 77 78func (r *Resolver) ResolveIdents(ctx context.Context, idents []string) []*identity.Identity { 79 results := make([]*identity.Identity, len(idents)) 80 var wg sync.WaitGroup 81 82 done := make(chan struct{}) 83 defer close(done) 84 85 for idx, ident := range idents { 86 wg.Add(1) 87 go func(index int, id string) { 88 defer wg.Done() 89 90 select { 91 case <-ctx.Done(): 92 results[index] = nil 93 case <-done: 94 results[index] = nil 95 default: 96 identity, _ := r.ResolveIdent(ctx, id) 97 results[index] = identity 98 } 99 }(idx, ident) 100 } 101 102 wg.Wait() 103 return results 104}