Files
at-container-registry/pkg/atproto/directory.go
T

62 lines
2.1 KiB
Go

package atproto
import (
"context"
"net"
"net/http"
"sync"
"time"
"github.com/bluesky-social/indigo/atproto/identity"
"github.com/earthboundkid/versioninfo/v2"
)
var (
// Shared identity directory instance (singleton)
sharedDirectory identity.Directory
directoryOnce sync.Once
)
// GetDirectory returns a shared identity.Directory instance with a 24-hour cache TTL.
// This is based on indigo's DefaultDirectory() with event-driven cache invalidation.
//
// Cache entries are invalidated via Jetstream events (identity changes, account status)
// which allows for a longer TTL while maintaining freshness. The Purge() method is called
// when identity or account events are received, ensuring the cache reflects real-time changes.
//
// Using a shared instance ensures all identity lookups across the application
// use the same cache, which is more memory-efficient and provides better cache hit rates.
func GetDirectory() identity.Directory {
directoryOnce.Do(func() {
base := identity.BaseDirectory{
PLCURL: identity.DefaultPLCURL,
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(),
}
// Cache configuration:
// - capacity: 250,000 entries
// - hitTTL: 24 hours (event-driven invalidation via Jetstream provides freshness)
// - errTTL: 2 minutes
// - invalidHandleTTL: 5 minutes
cached := identity.NewCacheDirectory(&base, 250_000, time.Hour*24, time.Minute*2, time.Minute*5)
sharedDirectory = &cached
})
return sharedDirectory
}