Как структурировать потребительский цикл MQ в Erlang / OTP? - PullRequest
0 голосов
/ 24 апреля 2019

Мне нужно создать простое приложение, которое использует очередь сообщений и асинхронно обрабатывает сообщения, используя Erlang / OTP.Рассмотрим этот псевдо-пример на Голанге:

var queue chan
func main() {
    for req := range queue {
        go handleRequest(req)  //handle asynchronously 
    }
}

Как исправить структуру следующих принципов OTP?
Я искал gen_server , но в этом случае, где я могуопределить мой цикл?
Кроме того, как я могу запустить асинхронный дескриптор?Должен ли я создать другого супервизора и использовать супервизор: start_child в каждом новом сообщении?

1 Ответ

1 голос
/ 26 апреля 2019

Модуль gen_server в стандартной библиотеке определяет рекурсивный цикл для вас. Единственное, что вам нужно сделать, это реализовать функции обратного вызова для обработки сообщений. Если очередь сообщений отправляет сообщения Erlang вашему процессу gen_server, вы должны сделать что-то вроде:

handle_info({incoming_request, Request}, _From, State) ->
    async_handle_request(Request),
    {noreply, State}.

Для асинхронной обработки запросов async_handle_request запускает процесс для каждого входящего запроса. Есть два способа сделать это: либо просто запустить процесс, либо запустить каждый процесс под simple_one_for_one супервизором. Различия сводятся к обработке ошибок и поведению выключения. Что вы делаете, если обработка запроса не удалась? Вы игнорируете ошибку, или позволяете ей распространяться на процесс gen_server, или у вас есть супервизор, перезапускающий процесс и повторяющий запрос?

Этот вопрос объясняет, когда вы можете использовать супервизор simple_one_for_one. Если вы просто хотите запустить процесс, это будет выглядеть так:

async_handle_request(Request) ->
    spawn_link(fun() -> handle_request(Request) end).

И тогда фактическая логика обработки запросов реализуется в handle_request.

...