Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

apidir fallback resolution; bluepages tweaks; hepa apidir support #986

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 55 additions & 3 deletions atproto/identity/apidir/apidir.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"log/slog"
"net/http"
"time"

Expand All @@ -21,6 +23,8 @@ type APIDirectory struct {
// API service to make queries to. Includes schema, hostname, and port, but no path or trailing slash. Eg: "http://localhost:6600"
Host string
UserAgent string
Fallback *identity.BaseDirectory
Logger *slog.Logger
}

var _ identity.Directory = (*APIDirectory)(nil)
Expand Down Expand Up @@ -56,6 +60,7 @@ func NewAPIDirectory(host string) APIDirectory {
},
Host: host,
UserAgent: "indigo-apidir/" + versioninfo.Short(),
Logger: slog.Default(),
}
}

Expand Down Expand Up @@ -136,6 +141,14 @@ func (dir *APIDirectory) ResolveDIDRaw(ctx context.Context, did syntax.DID) (jso
if err != nil {
didResolution.WithLabelValues("apidir", "error").Inc()
didResolutionDuration.WithLabelValues("apidir", "error").Observe(time.Since(start).Seconds())
if dir.Fallback != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this and ResolveHandle should check what kind of error like Lookup* ?
maybe make a helper for 'is api service error' ?

dir.Logger.Info("attempting fallback DID resolution", "did", did, "apiError", err)
start = time.Now()
raw, err := dir.Fallback.ResolveDIDRaw(ctx, did)
didResolution.WithLabelValues("apidir", "fallback").Inc()
didResolutionDuration.WithLabelValues("apidir", "fallback").Observe(time.Since(start).Seconds())
return raw, err
}
return nil, err
}
didResolution.WithLabelValues("apidir", "success").Inc()
Expand Down Expand Up @@ -166,6 +179,14 @@ func (dir *APIDirectory) ResolveHandle(ctx context.Context, handle syntax.Handle
if err != nil {
handleResolution.WithLabelValues("apidir", "error").Inc()
handleResolutionDuration.WithLabelValues("apidir", "error").Observe(time.Since(start).Seconds())
if dir.Fallback != nil {
dir.Logger.Info("attempting fallback handle resolution", "handle", handle, "apiError", err)
start = time.Now()
h, err := dir.Fallback.ResolveHandle(ctx, handle)
handleResolution.WithLabelValues("apidir", "fallback").Inc()
handleResolutionDuration.WithLabelValues("apidir", "fallback").Observe(time.Since(start).Seconds())
return h, err
}
return "", err
}
handleResolution.WithLabelValues("apidir", "success").Inc()
Expand All @@ -174,7 +195,7 @@ func (dir *APIDirectory) ResolveHandle(ctx context.Context, handle syntax.Handle
return body.DID, nil
}

func (dir *APIDirectory) Lookup(ctx context.Context, atid syntax.AtIdentifier) (*identity.Identity, error) {
func (dir *APIDirectory) apiLookup(ctx context.Context, atid syntax.AtIdentifier) (*identity.Identity, error) {
var body identityBody
u := dir.Host + "/xrpc/com.atproto.identity.resolveIdentity?identifier=" + atid.String()

Expand All @@ -200,12 +221,43 @@ func (dir *APIDirectory) Lookup(ctx context.Context, atid syntax.AtIdentifier) (
return &ident, nil
}

func (dir *APIDirectory) Lookup(ctx context.Context, atid syntax.AtIdentifier) (*identity.Identity, error) {
ident, err := dir.apiLookup(ctx, atid)
if err != nil && dir.Fallback != nil && (errors.Is(err, identity.ErrDIDResolutionFailed) || errors.Is(err, identity.ErrHandleResolutionFailed)) {
dir.Logger.Info("attempting fallback identity lookup", "identifier", atid, "apiError", err)
start := time.Now()
ident, err = dir.Fallback.Lookup(ctx, atid)
identityResolution.WithLabelValues("apidir", "fallback").Inc()
identityResolutionDuration.WithLabelValues("apidir", "fallback").Observe(time.Since(start).Seconds())
return ident, err
}
return ident, err
}

func (dir *APIDirectory) LookupHandle(ctx context.Context, handle syntax.Handle) (*identity.Identity, error) {
return dir.Lookup(ctx, handle.AtIdentifier())
ident, err := dir.apiLookup(ctx, handle.AtIdentifier())
if err != nil && dir.Fallback != nil && (errors.Is(err, identity.ErrDIDResolutionFailed) || errors.Is(err, identity.ErrHandleResolutionFailed)) {
dir.Logger.Info("attempting fallback handle lookup", "handle", handle, "apiError", err)
start := time.Now()
ident, err = dir.Fallback.LookupHandle(ctx, handle)
identityResolution.WithLabelValues("apidir", "fallback").Inc()
identityResolutionDuration.WithLabelValues("apidir", "fallback").Observe(time.Since(start).Seconds())
return ident, err
}
return ident, err
}

func (dir *APIDirectory) LookupDID(ctx context.Context, did syntax.DID) (*identity.Identity, error) {
return dir.Lookup(ctx, did.AtIdentifier())
ident, err := dir.apiLookup(ctx, did.AtIdentifier())
if err != nil && dir.Fallback != nil && (errors.Is(err, identity.ErrDIDResolutionFailed) || errors.Is(err, identity.ErrHandleResolutionFailed)) {
dir.Logger.Info("attempting fallback DID lookup", "did", did, "apiError", err)
start := time.Now()
ident, err = dir.Fallback.LookupDID(ctx, did)
identityResolution.WithLabelValues("apidir", "fallback").Inc()
identityResolutionDuration.WithLabelValues("apidir", "fallback").Observe(time.Since(start).Seconds())
return ident, err
}
return ident, err
}

func (dir *APIDirectory) Purge(ctx context.Context, atid syntax.AtIdentifier) error {
Expand Down
6 changes: 3 additions & 3 deletions atproto/identity/apidir/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var handleResolution = promauto.NewCounterVec(prometheus.CounterOpts{
var handleResolutionDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "atproto_identity_apidir_resolve_handle_duration",
Help: "Time to resolve a handle",
Buckets: prometheus.ExponentialBucketsRange(0.001, 2, 15),
Buckets: prometheus.ExponentialBuckets(0.0001, 2, 20),
}, []string{"directory", "status"})

var didResolution = promauto.NewCounterVec(prometheus.CounterOpts{
Expand All @@ -24,7 +24,7 @@ var didResolution = promauto.NewCounterVec(prometheus.CounterOpts{
var didResolutionDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "atproto_identity_apidir_resolve_did_duration",
Help: "Time to resolve a DID",
Buckets: prometheus.ExponentialBucketsRange(0.001, 2, 15),
Buckets: prometheus.ExponentialBuckets(0.0001, 2, 20),
}, []string{"directory", "status"})

var identityResolution = promauto.NewCounterVec(prometheus.CounterOpts{
Expand All @@ -35,5 +35,5 @@ var identityResolution = promauto.NewCounterVec(prometheus.CounterOpts{
var identityResolutionDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "atproto_identity_apidir_resolve_identity_duration",
Help: "Time to resolve a combined identity",
Buckets: prometheus.ExponentialBucketsRange(0.001, 2, 15),
Buckets: prometheus.ExponentialBuckets(0.0001, 2, 20),
}, []string{"directory", "status"})
4 changes: 2 additions & 2 deletions atproto/identity/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var handleResolution = promauto.NewCounterVec(prometheus.CounterOpts{
var handleResolutionDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "atproto_identity_resolve_handle_duration",
Help: "Time to resolve a handle",
Buckets: prometheus.ExponentialBucketsRange(0.001, 2, 15),
Buckets: prometheus.ExponentialBuckets(0.0001, 2, 20),
}, []string{"directory", "status"})

var didResolution = promauto.NewCounterVec(prometheus.CounterOpts{
Expand All @@ -24,5 +24,5 @@ var didResolution = promauto.NewCounterVec(prometheus.CounterOpts{
var didResolutionDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "atproto_identity_resolve_did_duration",
Help: "Time to resolve a DID",
Buckets: prometheus.ExponentialBucketsRange(0.001, 2, 15),
Buckets: prometheus.ExponentialBuckets(0.0001, 2, 20),
}, []string{"directory", "status"})
4 changes: 2 additions & 2 deletions atproto/identity/redisdir/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var handleResolution = promauto.NewCounterVec(prometheus.CounterOpts{
var handleResolutionDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "atproto_identity_redisdir_resolve_handle_duration",
Help: "Time to resolve a handle",
Buckets: prometheus.ExponentialBucketsRange(0.001, 2, 15),
Buckets: prometheus.ExponentialBuckets(0.0001, 2, 20),
}, []string{"directory", "status"})

var didResolution = promauto.NewCounterVec(prometheus.CounterOpts{
Expand All @@ -24,5 +24,5 @@ var didResolution = promauto.NewCounterVec(prometheus.CounterOpts{
var didResolutionDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "atproto_identity_redisdir_resolve_did_duration",
Help: "Time to resolve a DID",
Buckets: prometheus.ExponentialBucketsRange(0.001, 2, 15),
Buckets: prometheus.ExponentialBuckets(0.0001, 2, 20),
}, []string{"directory", "status"})
Loading
Loading