Как дела выборочный получает в gen_servers?

Слон в комнате: Фокусировка на микрооптимизации уровня реализации вместо на лучших алгоритмах.

7
задан mwt 17 August 2009 в 21:42
поделиться

4 ответа

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

handle_cast(test, _State) ->
    ...
    {noreply, {[1,2,4,5,6,7,8,9], []}};

handle_cast({result, N}, {Wait, Buff}) ->
    {noreply, handle_results(Wait, [N|Buff])}.

handle_results([], Buff) ->
    {[], Buff};

handle_results([W|WTail] = Wait, Buff) ->
    case lists:member(W, Buff) of
        true ->
            io:format("result: " ++ integer_to_list(W) ++ "~n"),
            handle_results(WTail, Buff -- [W]);
        false ->
            {Wait, Buff}
    end.
4
ответ дан 6 December 2019 в 09:20
поделиться

Нет, gen_server не предназначен для обработки выборочного приема, каждый запрос обрабатывается по мере его поступления. На самом деле это сложная проблема, так как Erlang требует, чтобы все шаблоны были известны во время компиляции, не существует "объекта шаблона".

Я согласен, что gen_fsm, вероятно, тоже не для вас, поскольку он не принимает различные сообщения, поступающие в любой порядок, прежде чем вы получите взрыв в количестве состояний. Это была одна из причин, по которой мы добавили выборочный прием, он позволяет вам безопасно игнорировать неинтересные сообщения, оставляя их на потом.

Какой OTP вас особенно интересует?

4
ответ дан 6 December 2019 в 09:20
поделиться

Тот факт, что вы не можете использовать gen_server для одного из ваших модулей, не означает, что вы не используете OTP. Все модули обратного вызова реализуют для вас блок приема, который не позволяет использовать выборочный прием. Нет причин, по которым вы не можете реализовать свой собственный сервис, который обрабатывает выборочный прием. И это не означает, что вы не сделали это методом OTP.

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

2
ответ дан 6 December 2019 в 09:20
поделиться

Возможно, вы действительно хотите использовать gen_fsm. Такое поведение обычно выбирается во внешнем интерфейсе для протоколов, где протокол имеет определенные состояния и должен обрабатывать запросы по-разному в зависимости от того, в каком состоянии он сейчас находится.

Но вернемся к gen_server, мы используем gen_server для его функций. Он подписывается на системные события для загрузки кода и дает вам обратный вызов code_change. Вызывает sasl-отчеты о сбоях. Вы получаете хорошо известную структуру, которая помогает поддерживать код. Что наиболее важно, он реализует хорошо разработанный протокол для синхронных вызовов.

Трудно сказать, подходит ли вам поведение OTP в данном случае.


Учитывая комментарий, похоже, что gen_server вам не подходит. Когда я использую поведение gen_server, я думаю о нем как о начальнике в компании. Все хотят поговорить с начальником, поэтому в интересах компании сделать так, чтобы босс мог быстро и эффективно делегировать задания, чтобы он не позволял людям сидеть и ждать вместо работы.

gen_server может делегировать полномочия, используя параметр 'From'. Для этого верните {no_reply, State} и передайте параметр From делегату. Делегат использует gen_server: reply / 2 , чтобы ответить на исходный вызов.

Этот метод использования gen_server может быть для вас. Запустите «простой» процесс, в котором вы используете приемный конец для выборочного приема. Если это действительно независимая работа, gen_server может ее игнорировать (запустить и забыть). Если он хочет знать, завершен ли он, он может gen_server: cast / 2 отправить ему сообщение из запущенного «простого» процесса.

Если вы хотите заблокировать gen_server во время выборочного приема, то можно было бы также запустить процесс и дождаться его смерти перед возвратом. Выборочный прием - это линейный поиск сообщений в порядке их поступления за O (n). Таким образом, каждый выборочный прием будет сканировать все сообщения в очереди, что может быть высоким для популярного gen_server.

Ни одна компания не должна иметь только боссов, работающих там. Ни одно приложение на Erlang не должно иметь только gen_servers.

Ни в одной компании не должно быть только боссов. Ни одно приложение на Erlang не должно иметь только gen_servers.

Ни в одной компании не должно быть только боссов. Ни одно приложение на Erlang не должно иметь только gen_servers.

3
ответ дан 6 December 2019 в 09:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: