From 5bd87b462e1b020feb232fefaf4926ff004eefe4 Mon Sep 17 00:00:00 2001 From: Orual Date: Thu, 11 Dec 2025 19:24:53 -0500 Subject: [PATCH] tracing span issue caused weirdness --- crates/jacquard-common/src/types/aturi.rs | 36 ++++++++++++++++++ crates/jacquard/src/client.rs | 45 ++++++++++++++++------- 2 files changed, 68 insertions(+), 13 deletions(-) diff --git a/crates/jacquard-common/src/types/aturi.rs b/crates/jacquard-common/src/types/aturi.rs index e8f84925..82511342 100644 --- a/crates/jacquard-common/src/types/aturi.rs +++ b/crates/jacquard-common/src/types/aturi.rs @@ -1,3 +1,4 @@ +use crate::cowstr::ToCowStr; use crate::types::ident::AtIdentifier; use crate::types::nsid::Nsid; use crate::types::recordkey::{RecordKey, Rkey}; @@ -106,6 +107,16 @@ pub struct RepoPath<'u> { pub rkey: Option>>, } +impl fmt::Display for RepoPath<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "/{}", self.collection)?; + if let Some(rkey) = &self.rkey { + write!(f, "/{}", rkey.as_ref())?; + } + Ok(()) + } +} + impl IntoStatic for RepoPath<'_> { type Output = RepoPath<'static>; @@ -341,6 +352,31 @@ impl<'u> AtUri<'u> { } impl AtUri<'static> { + /// Fallible owned constructor from typical parts + pub fn from_parts_owned( + authority: impl AsRef, + collection: impl AsRef, + rkey: impl AsRef, + ) -> Result { + let (authority, collection, rkey) = + (authority.as_ref(), collection.as_ref(), rkey.as_ref()); + if authority.is_empty() || (collection.is_empty() && !rkey.is_empty()) { + Err(AtStrError::missing( + "at-uri-scheme", + &format!("at://{}/{}/{}", authority, collection, rkey), + "correct uri path", + )) + } else if !authority.is_empty() && collection.is_empty() && rkey.is_empty() { + let uri = format!("at://{}", authority); + Self::new_owned(uri) + } else if !collection.is_empty() && rkey.is_empty() { + let uri = format!("at://{}/{}", authority, collection); + Self::new_owned(uri) + } else { + let uri = format!("at://{}/{}/{}", authority, collection, rkey); + Self::new_owned(uri) + } + } /// Owned constructor /// /// Uses ouroboros self-referential tricks internally to make sure everything diff --git a/crates/jacquard/src/client.rs b/crates/jacquard/src/client.rs index d5c0db80..ea7e42be 100644 --- a/crates/jacquard/src/client.rs +++ b/crates/jacquard/src/client.rs @@ -667,9 +667,6 @@ pub trait AgentSessionExt: AgentSession + IdentityResolver { R: Collection + serde::Serialize, { async move { - #[cfg(feature = "tracing")] - let _span = tracing::debug_span!("create_record", collection = %R::nsid()).entered(); - use jacquard_api::com_atproto::repo::create_record::CreateRecord; use jacquard_common::types::ident::AtIdentifier; use jacquard_common::types::value::to_data; @@ -679,6 +676,9 @@ pub trait AgentSessionExt: AgentSession + IdentityResolver { .await .ok_or_else(AgentError::no_session)?; + #[cfg(feature = "tracing")] + let _span = tracing::debug_span!("create_record", collection = %R::nsid()).entered(); + let data = to_data(&record).map_err(|e| AgentError::sub_operation("serialize record", e))?; @@ -689,6 +689,9 @@ pub trait AgentSessionExt: AgentSession + IdentityResolver { .maybe_rkey(rkey) .build(); + #[cfg(feature = "tracing")] + _span.exit(); + let response = self.send(request).await?; response.into_output().map_err(|e| match e { XrpcError::Auth(auth) => AgentError::from(auth), @@ -753,6 +756,9 @@ pub trait AgentSessionExt: AgentSession + IdentityResolver { .with_help("ensure the URI includes a record key after the collection") })?; + #[cfg(feature = "tracing")] + _span.exit(); + // Resolve authority (DID or handle) to get DID and PDS use jacquard_common::types::ident::AtIdentifier; let (repo_did, pds_url) = match uri.authority() { @@ -818,6 +824,9 @@ pub trait AgentSessionExt: AgentSession + IdentityResolver { .rkey(rkey.clone()) .build(); + #[cfg(feature = "tracing")] + _span.exit(); + let response: Response = { use url::Url; @@ -918,13 +927,13 @@ pub trait AgentSessionExt: AgentSession + IdentityResolver { for<'a> CollectionError<'a, R>: Send + Sync + std::error::Error + IntoStatic, { async move { + // Fetch the record - Response where R::Record::Output<'de> = R<'de> + let response = self.get_record::(uri).await?; + #[cfg(feature = "tracing")] let _span = tracing::debug_span!("update_record", collection = %R::nsid(), uri = %uri) .entered(); - // Fetch the record - Response where R::Record::Output<'de> = R<'de> - let response = self.get_record::(uri).await?; - // Parse to get R<'_> borrowing from response buffer let record = response.parse().map_err(|e| match e { XrpcError::Auth(auth) => AgentError::from(auth), @@ -952,6 +961,9 @@ pub trait AgentSessionExt: AgentSession + IdentityResolver { })? .clone() .into_static(); + + #[cfg(feature = "tracing")] + _span.exit(); self.put_record::(rkey, owned).await } } @@ -968,23 +980,25 @@ pub trait AgentSessionExt: AgentSession + IdentityResolver { R: Collection, { async { + let (did, _) = self + .session_info() + .await + .ok_or_else(AgentError::no_session)?; #[cfg(feature = "tracing")] let _span = tracing::debug_span!("delete_record", collection = %R::nsid()).entered(); use jacquard_api::com_atproto::repo::delete_record::DeleteRecord; use jacquard_common::types::ident::AtIdentifier; - let (did, _) = self - .session_info() - .await - .ok_or_else(AgentError::no_session)?; - let request = DeleteRecord::new() .repo(AtIdentifier::Did(did)) .collection(R::nsid()) .rkey(rkey) .build(); + #[cfg(feature = "tracing")] + _span.exit(); + let response = self.send(request).await?; response.into_output().map_err(|e| match e { XrpcError::Auth(auth) => AgentError::from(auth), @@ -1029,6 +1043,9 @@ pub trait AgentSessionExt: AgentSession + IdentityResolver { .record(data) .build(); + #[cfg(feature = "tracing")] + _span.exit(); + let response = self.send(request).await?; response.into_output().map_err(|e| match e { XrpcError::Auth(auth) => AgentError::from(auth), @@ -1081,9 +1098,11 @@ pub trait AgentSessionExt: AgentSession + IdentityResolver { http::HeaderValue::from_str(mime_type.as_str()) .map_err(|e| AgentError::sub_operation("set Content-Type header", e))?, )); + + #[cfg(feature = "tracing")] + _span.exit(); + let response = self.send_with_opts(request, opts).await?; - let debug: serde_json::Value = serde_json::from_slice(response.buffer()).unwrap(); - println!("json: {}", serde_json::to_string_pretty(&debug).unwrap()); let output = response.into_output().map_err(|e| match e { XrpcError::Auth(auth) => AgentError::from(auth), e @ (XrpcError::Generic(_) | XrpcError::Decode(_)) => AgentError::xrpc(e), -- 2.51.2