mirror of
https://github.com/LukeMathWalker/zero-to-production.git
synced 2025-02-07 14:32:21 +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::domain::SubscriberEmail;
|
||||||
use crate::email_client::EmailClient;
|
use crate::email_client::EmailClient;
|
||||||
use crate::routes::error_chain_fmt;
|
use crate::routes::error_chain_fmt;
|
||||||
|
use crate::telemetry::spawn_blocking_with_tracing;
|
||||||
use actix_web::http::{HeaderMap, HeaderValue, StatusCode};
|
use actix_web::http::{HeaderMap, HeaderValue, StatusCode};
|
||||||
use actix_web::{web, HttpResponse, ResponseError};
|
use actix_web::{web, HttpResponse, ResponseError};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
@ -114,23 +115,36 @@ async fn validate_credentials(
|
||||||
.map_err(PublishError::UnexpectedError)?
|
.map_err(PublishError::UnexpectedError)?
|
||||||
.ok_or_else(|| PublishError::AuthError(anyhow::anyhow!("Unknown username.")))?;
|
.ok_or_else(|| PublishError::AuthError(anyhow::anyhow!("Unknown username.")))?;
|
||||||
|
|
||||||
let expected_password_hash = PasswordHash::new(&expected_password_hash)
|
spawn_blocking_with_tracing(move || {
|
||||||
.context("Failed to parse hash in PHC string format.")
|
verify_password_hash(expected_password_hash, credentials.password)
|
||||||
.map_err(PublishError::UnexpectedError)?;
|
})
|
||||||
|
.await
|
||||||
tracing::info_span!("Verify password hash")
|
.context("Failed to spawn blocking task.")
|
||||||
.in_scope(|| {
|
.map_err(PublishError::UnexpectedError)??;
|
||||||
Argon2::default()
|
|
||||||
.verify_password(credentials.password.as_bytes(), &expected_password_hash)
|
|
||||||
})
|
|
||||||
.context("Invalid password.")
|
|
||||||
.map_err(PublishError::AuthError)?;
|
|
||||||
|
|
||||||
Ok(user_id)
|
Ok(user_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(
|
#[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),
|
skip(body, pool, email_client, request),
|
||||||
fields(username=tracing::field::Empty, user_id=tracing::field::Empty)
|
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::set_global_default;
|
||||||
use tracing::Subscriber;
|
use tracing::Subscriber;
|
||||||
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
|
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");
|
LogTracer::init().expect("Failed to set logger");
|
||||||
set_global_default(subscriber).expect("Failed to set subscriber");
|
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