Запустить асинхронную функцию в определенном потоке - PullRequest
0 голосов
/ 12 ноября 2018

Я хотел бы запускать определенные длительные функции (которые выполняют запросы к базе данных) в отдельном потоке. Однако давайте предположим, что базовый механизм базы данных допускает только одно соединение за раз, а структура соединения не Sync (я думаю, что по крайней мере последнее верно для diesel).

Мое решение состояло бы в том, чтобы иметь один отдельный поток (в отличие от пула потоков), в котором выполняется вся работа с базой данных и который выполняется, пока основной поток жив. Я думаю, что знаю, как мне пришлось бы делать это с передачей сообщений по каналам, но для этого требуется довольно много стандартного кода (например, явная отправка аргументов функции по каналу и т. Д.).

Есть ли более прямой способ достижения чего-то подобного с помощью ржавчины (и, возможно, Tokio и новой нотации async / await, которая появляется ночью)?

Я надеюсь сделать что-то вроде:

let handle = spawn_thread_with_runtime(...);

let future = run_on_thread!(handle, query_function, argument1, argument2);

где query_function будет функцией, которая немедленно возвращает будущее и выполняет работу в другом потоке.

Ночная ржавчина и внешние ящики / макросы будут в порядке.

1 Ответ

0 голосов
/ 12 ноября 2018

Если есть возможность выбрать внешние ящики, я бы рассмотрел actix , Actor Framework для Rust.

Это позволит вам создать актера в отдельном потоке, который фактически владеет соединением с БД. Затем он может прослушивать сообщения, выполнять работу / запросы на основе этих сообщений и возвращать либо результаты синхронизации, либо фьючерсы.

Он заботится о большей части шаблона для передачи сообщений, нереста и т. Д. На более высоком уровне.

В документации actix есть также дизельный пример , который звучит довольно близко к тому сценарию использования, который вы имели в виду.

...