mirror of
https://github.com/LukeMathWalker/zero-to-production.git
synced 2025-01-31 11:02:29 +00:00
Do not lose context when using spawn blocking.
This commit is contained in:
parent
db0ebb4828
commit
00ab3e9252
2 changed files with 36 additions and 12 deletions
|
@ -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)
|
||||
)]
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue