feat(at-identity): PdsHandleResolver for cluster-local DID→handle resolution
The AppView's handle_sync worker consulted the public PLC directory and the did:web: HTTPS resolver only. DIDs hosted on the local PDS (notably did🔑 users and any other operator-hosted method) weren't reachable without an external round trip, and unresolvable DIDs (did🔑 not on this PDS, did:foo: anything) blocked the 100-row batch forever because did🔑 sorts lexicographically before did:plc: / did:web:. This commit adds: * `PdsHandleResolver` (at-identity) — POSTs the DID as the `handle` field to the PDS's resolveHandle XRPC method. The PDS now recognises a `did:` prefix and does a PK lookup on `users.did`, returning `{did, handle}`. The resolver reads the `handle` field, so the AppView finally gets a real local handle for did🔑 users without ever dialing plc.directory. * A 2 s timeout per request (was 10 s) and `DISPATCH_CONCURRENCY = 8` so the worker caps a 100-DID batch at ~2 s with parallel dispatch instead of the ~17 min worst case the old serial + 10 s setup allowed. * A new `posts.handle_sync_attempted_at` column (migration 0006) and `mark_attempted()` helper. The SELECT filter excludes rows attempted within the last hour, so an unresolvable DID dominates at most one batch before the worker advances. Cleared on success. * `PDS_INTERNAL_URL` config so the AppView can reach the PDS via a cluster-internal hostname when the public URL isn't routable from inside the cluster. Tests: * `crates/at-identity/src/pds_handle.rs` — 4 unit tests against a stub HTTP server (200/404/5xx/missing-did-field). * Existing handle_sync integration tests updated to wire in the new `pds_resolver` field.
This commit is contained in:
@@ -28,6 +28,14 @@ pub struct AppConfig {
|
||||
pub s3_bucket_pds: String,
|
||||
pub s3_bucket_appview: String,
|
||||
pub plc_directory_url: String,
|
||||
/// Cluster-internal URL the AppView uses to reach the PDS (e.g.
|
||||
/// `http://pds-server:3000`). Falls back to `pds_public_url` when
|
||||
/// unset. Splitting this from `pds_public_url` lets a single
|
||||
/// deployment point the AppView at the in-cluster PDS hostname
|
||||
/// (which may not be reachable from outside) while clients
|
||||
/// still see the public URL.
|
||||
#[serde(default)]
|
||||
pub pds_internal_url: Option<String>,
|
||||
/// Optional shared secret for `POST /internal/ingest-commit`. If unset,
|
||||
/// the endpoint accepts anonymous requests (dev mode). If set, callers
|
||||
/// must send `X-Ingest-Secret: <value>`.
|
||||
@@ -68,6 +76,7 @@ impl AppConfig {
|
||||
s3_bucket_pds: env("S3_BUCKET_PDS")?,
|
||||
s3_bucket_appview: env("S3_BUCKET_APPVIEW")?,
|
||||
plc_directory_url: env("PLC_DIRECTORY_URL")?,
|
||||
pds_internal_url: std::env::var("PDS_INTERNAL_URL").ok(),
|
||||
appview_ingest_secret: std::env::var("APPVIEW_INGEST_SECRET").ok(),
|
||||
appview_handle_sync_interval_secs: std::env::var("APPVIEW_HANDLE_SYNC_INTERVAL_SECS")
|
||||
.ok()
|
||||
|
||||
Reference in New Issue
Block a user