Вы можете использовать Actix Arbiter
для планирования асинхронной задачи:
use actix::Arbiter;
async fn do_the_database_stuff(
email: String,
pool: web::Data<Pool>,
redis_client: web::Data<redis::Client>)
{
// async database code here
}
pub async fn forgot_password_handler(
email_from_path: web::Path<String>,
pool: web::Data<Pool>,
redis_client: web::Data<redis::Client>,
) -> HttpResponse {
let email = email_from_path.clone();
Arbiter::spawn(async {
do_the_database_stuff(
email,
pool,
redis_client
);
});
HttpResponse::Ok().finish()
}
Если код вашей базы данных блокируется, чтобы предотвратить перегрузку долгоживущих рабочих потоков Actix, вместо создайте новый Arbiter
со своим собственным потоком:
fn do_the_database_stuff(email: String) {
// blocking database code here
}
pub async fn forgot_password_handler(email_from_path: String) -> HttpResponse {
let email = email_from_path.clone();
Arbiter::new().exec_fn(move || {
async move {
do_the_database_stuff(email).await;
};
});
HttpResponse::Ok().finish()
}
Это может потребовать немного больше работы, потому что Pool
и redis::Client
вряд ли будут безопасно делиться между потоками, поэтому у вас будет чтобы решить и это. Вот почему я не включил их в пример кода.
Лучше использовать Arbiter
s, чем поддаваться соблазну создать новый собственный поток с std::thread
. Если вы смешаете их, вы можете случайно включить код, который нарушит работу воркера. Например, использование std::thread::sleep
в контексте async
приведет к приостановке несвязанных задач, которые случайно были запланированы для одного и того же воркера, и может даже не повлиять на поставленную вами задачу.
Наконец , вы также можете подумать об изменении архитектуры. Если вы разложите задачи, связанные с базами данных, на их собственные микросервисы, вы решите эту проблему автоматически. Затем веб-обработчик может просто отправить сообщение (Kafka, RabbitMQ, ZMQ, HTTP или что угодно по вашему выбору) и немедленно вернуться. Это позволит вам масштабировать микросервисы независимо от веб-сервера - 10 экземпляров веб-сервера не обязательно означают 10 подключений к базе данных, если вам нужен только один экземпляр для службы сброса пароля.