Do not lose context when using spawn blocking.

This commit is contained in:
Luca Palmieri 2021-08-30 16:28:01 +02:00
parent db0ebb4828
commit 00ab3e9252
2 changed files with 36 additions and 12 deletions

View file

@ -1,6 +1,7 @@
use crate::domain::SubscriberEmail;
use crate::email_client::EmailClient;
use crate::routes::error_chain_fmt;
use crate::telemetry::spawn_blocking_with_tracing;
use actix_web::http::{HeaderMap, HeaderValue, StatusCode};
use actix_web::{web, HttpResponse, ResponseError};
use anyhow::Context;
@ -114,23 +115,36 @@ async fn validate_credentials(
.map_err(PublishError::UnexpectedError)?
.ok_or_else(|| PublishError::AuthError(anyhow::anyhow!("Unknown username.")))?;
let expected_password_hash = PasswordHash::new(&expected_password_hash)
.context("Failed to parse hash in PHC string format.")
.map_err(PublishError::UnexpectedError)?;
tracing::info_span!("Verify password hash")
.in_scope(|| {
Argon2::default()
.verify_password(credentials.password.as_bytes(), &expected_password_hash)
})
.context("Invalid password.")
.map_err(PublishError::AuthError)?;
spawn_blocking_with_tracing(move || {
verify_password_hash(expected_password_hash, credentials.password)
})
.await
.context("Failed to spawn blocking task.")
.map_err(PublishError::UnexpectedError)??;
Ok(user_id)
}
#[tracing::instrument(
name = "Publish a newsletter issue",
name = "Validate credentials",
skip(expected_password_hash, password_candidate)
)]
fn verify_password_hash(
expected_password_hash: String,
password_candidate: String,
) -> Result<(), PublishError> {
let expected_password_hash = PasswordHash::new(&expected_password_hash)
.context("Failed to parse hash in PHC string format.")
.map_err(PublishError::UnexpectedError)?;
Argon2::default()
.verify_password(password_candidate.as_bytes(), &expected_password_hash)
.context("Invalid password.")
.map_err(PublishError::AuthError)
}
#[tracing::instrument(
name = "Publish a newsletter issue",
skip(body, pool, email_client, request),
fields(username=tracing::field::Empty, user_id=tracing::field::Empty)
)]

View file

@ -1,3 +1,4 @@
use actix_web::rt::task::JoinHandle;
use tracing::subscriber::set_global_default;
use tracing::Subscriber;
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
@ -32,3 +33,12 @@ pub fn init_subscriber(subscriber: impl Subscriber + Sync + Send) {
LogTracer::init().expect("Failed to set logger");
set_global_default(subscriber).expect("Failed to set subscriber");
}
pub fn spawn_blocking_with_tracing<F, R>(f: F) -> JoinHandle<R>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
let current_span = tracing::Span::current();
actix_web::rt::task::spawn_blocking(move || current_span.in_scope(f))
}