forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
at knot-cli 2.5 kB view raw
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 return redisdir.NewRedisDirectory(BaseDirectory(), url, time.Hour*24, time.Hour*1, time.Hour*1, 10000) 48} 49 50func DefaultResolver() *Resolver { 51 return &Resolver{ 52 directory: identity.DefaultDirectory(), 53 } 54} 55 56func RedisResolver(config config.RedisConfig) (*Resolver, error) { 57 directory, err := RedisDirectory(config.ToURL()) 58 if err != nil { 59 return nil, err 60 } 61 return &Resolver{ 62 directory: directory, 63 }, nil 64} 65 66func (r *Resolver) ResolveIdent(ctx context.Context, arg string) (*identity.Identity, error) { 67 id, err := syntax.ParseAtIdentifier(arg) 68 if err != nil { 69 return nil, err 70 } 71 72 return r.directory.Lookup(ctx, *id) 73} 74 75func (r *Resolver) ResolveIdents(ctx context.Context, idents []string) []*identity.Identity { 76 results := make([]*identity.Identity, len(idents)) 77 var wg sync.WaitGroup 78 79 done := make(chan struct{}) 80 defer close(done) 81 82 for idx, ident := range idents { 83 wg.Add(1) 84 go func(index int, id string) { 85 defer wg.Done() 86 87 select { 88 case <-ctx.Done(): 89 results[index] = nil 90 case <-done: 91 results[index] = nil 92 default: 93 identity, _ := r.ResolveIdent(ctx, id) 94 results[index] = identity 95 } 96 }(idx, ident) 97 } 98 99 wg.Wait() 100 return results 101}