Skip to content
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
5 changes: 4 additions & 1 deletion hotshot-query-service/src/data_source/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,10 @@ macro_rules! function_name {
}
let full: &'static str = type_name_of(__f);
let trimmed: &'static str = full.strip_suffix("::__f").unwrap_or(full);
trimmed.rsplit("::").next().unwrap_or(trimmed)
trimmed
.rsplit("::")
.find(|segment| *segment != "{{closure}}")
.unwrap_or(trimmed)
}};
}

Expand Down
39 changes: 37 additions & 2 deletions hotshot-query-service/src/data_source/storage/sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,11 +836,10 @@ fn serialization_conflict_with_diag<E: std::fmt::Display>(
fn spawn_pg_stat_activity_log(pool: Pool<Db>, op: &'static str) {
use sqlx::Row as _;
tokio::spawn(async move {
// Log concurrent sessions
match sqlx::query(
"SELECT pid, COALESCE(state, 'unknown') AS state, left(COALESCE(query, ''), 200) AS \
query FROM pg_stat_activity WHERE pid != pg_backend_pid() AND state IS DISTINCT FROM \
'idle'",
'idle' AND usename = current_user",
)
.fetch_all(&pool)
.await
Expand Down Expand Up @@ -1069,6 +1068,42 @@ mod serializable_retry_tests {
}
assert_eq!(télécharger(), "télécharger");
}

/// Verify that [`function_name!`](crate::function_name) resolves to the function name even from
/// `async` contexts, where the body is lowered into a generator/closure. This is the case that
/// every production call site hits, and a naive macro reports `{{closure}}` here.
#[test_log::test(tokio::test)]
async fn test_function_name_macro_async() {
// Plain `async fn`: the body becomes a generator, adding a `{{closure}}` path segment.
async fn plain_async_fn() -> &'static str {
crate::function_name!()
}
assert_eq!(plain_async_fn().await, "plain_async_fn");

// Closure returning an async block inside an `async fn`, mirroring the real
// `serializable_retry!(self, || async { .. })` call sites: adds multiple `{{closure}}`
// segments to the path.
async fn nested_async_blocks() -> &'static str {
let f = || async { crate::function_name!() };
f().await
}
assert_eq!(nested_async_blocks().await, "nested_async_blocks");

// `#[async_trait]` method: the body is rewritten to `Box::pin(async move { .. })`, exactly
// as the real `serializable_retry!` call sites are.
struct S;
#[async_trait::async_trait]
trait T {
async fn async_trait_method(&self) -> &'static str;
}
#[async_trait::async_trait]
impl T for S {
async fn async_trait_method(&self) -> &'static str {
crate::function_name!()
}
}
assert_eq!(S.async_trait_method().await, "async_trait_method");
}
}

impl PrunerConfig for SqlStorage {
Expand Down
Loading