Фон
Я работаю над веб-приложением actix, использующим дизель через r2d2, и не знаю, как лучше всего выполнять асинхронные запросы. Я нашел три варианта, которые кажутся разумными, но я не уверен, какой из них лучше.
Потенциальные решения
Синхронный актер
Для одного я мог бы использовать actixпример , но он довольно сложный и требует изрядного количества шаблонов для сборки. Я надеюсь, что существует более разумное решение.
Actix_web::web::block
В качестве другого варианта я мог бы использовать actix_web::web::block
, чтобы обернуть свои функции запросов в будущее, ноЯ не уверен, что это повлияет на производительность.
Запускается ли тогда запрос в той же системе Tokio? Из того, что я мог найти в источнике, создает поток в базовом пуле потоков actix-web . Это проблема?
Если я правильно прочитал код, r2d2 блокирует свой поток при получении соединения, что блокирует часть основного пула actix-web. То же самое с запросами к базе данных. Это тогда заблокировало бы все actix-web, если я делаю больше запросов, чем у меня потоков в этом пуле? Если это так, большая проблема.
Futures-cpupool
Наконец, безопасная ставка, которая может иметь некоторые ненужные накладные расходы, составляет futures-cpupool . Основная проблема заключается в том, что это означает добавление еще одного ящика в мой проект, хотя мне не нравится идея, что в моем приложении будет ненужно использовать несколько процессорных пулов.
Поскольку и r2d2, и дизель будут блокировать, существуетЗдесь удивительное количество хитрых вещей.
Самое главное, не делитесь этим cpupool с тем, что не использует тот же пул r2d2 (поскольку все созданные потоки могут просто блокировать ожидание соединения r2d2, блокируя весь пул, когдаработа существует).
Во-вторых (немного более очевидно), таким образом, вы не должны иметь больше соединений r2d2, чем потоков в пуле, и наоборот, так как большее соединение будет тратить ресурсы (неиспользуемые соединения / потоки постоянно блокируются). ) (возможно, еще один поток, возможно, для более быстрой передачи соединений планировщиком ОС, а не планировщиком cpupool).
Наконец, обратите внимание, какую базу данных вы используете, и какую производительность вы там выполняете. Выполнение одного соединения r2d2 и одного потока в пуле может быть лучше в приложении с тяжелой записью sqlite (хотя я бы порекомендовал подходящую базу данных для этого).
Старые ответы
Старые решения, которыеможет работать
https://www.reddit.com/r/rust/comments/axy0hp/patterns_to_scale_actixweb_and_diesel/
По сути, рекомендует Futures-cpupool.
Каков наилучший подход для инкапсуляции блокирующих операций ввода-вывода в будущем?
Рекомендует Futures-cpupool для общих случаев.
Старые решения, которые не работают
https://www.reddit.com/r/rust/comments/9fe1ye/noob_here_can_we_talk_about_async_and_databases/
Действительно хорошее решение длястарая веб-версия actix. Из того, что я могу найти, запросы больше не содержат пул процессоров.