межпроцессная многоадресная рассылка erlang

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

  1. отправлять каждое сообщение главному процессу, который отправляет сообщение остальной части группы, мне это кажется узким местом!.
  2. используйте глобальную таблицу ets, которая содержит все идентификаторы группы (чрезмерное копирование).
  3. используйте многоадресную рассылку upd.
  4. модуль pg, который совпадает с 1.

каков наилучший подход, есть ли другие альтернативы?


person user1748906    schedule 17.10.2012    source источник
comment
Какого размера вы ожидаете от групп? Ответ будет другим для групп из 10 и групп из одного миллиона человек.   -  person Marcelo Cantos    schedule 17.10.2012
comment
100 групп, каждая содержит 100 клиентов, отправляющих текст, сжатое видео и аудио.   -  person user1748906    schedule 17.10.2012
comment
Тогда я сомневаюсь, что вы увидите какие-либо серьезные проблемы с вариантом 1. видео и аудио — я полагаю, выраженные в виде двоичных файлов — будут иметь тенденцию попадать в глобальную кучу, а не копироваться.   -  person Marcelo Cantos    schedule 17.10.2012


Ответы (2)


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

Не стоит недооценивать сохранение процесса, который работает как мультикастер для группы. Это может быть простое решение, хотя просто хранить pid() в таблице ETS или использовать для него gproc может быть примерно то же самое.

Беспокойство о чрезмерном копировании, вероятно, не будет плодотворным в начале. Хитрость здесь может заключаться в том, чтобы сохранить сообщение в виде большого двоичного файла, а затем отправить его. Тогда, как пишет Марсело, вам останется только обойти референс.

Я бы избегал решения Вэнса Шипли о связывании. Ссылки являются двунаправленными, и вам придется перехватывать выходы, чтобы получить выходное сообщение. Вероятно, лучше поддерживать жизненные знания с помощью вызова erlang:monitor(process, Pid). Вам нужно будет сделать это, так как процесс, который уходит, должен быть удален из группы. Получение сообщения вида {'DOWN', ..., ...} будет признаком того, что вам нужно позаботиться об очистке.

person I GIVE CRAP ANSWERS    schedule 18.10.2012
comment
хотя я искал что-то более эффективное, например, TChan в Haskell, но отличный ответ. - person user1748906; 19.10.2012
comment
Haskells STM.TChan не выполняет многоадресную рассылку IIRC. Это неограниченный канал FIFO, и он не имеет разветвления. - person I GIVE CRAP ANSWERS; 20.10.2012

Более естественным методом было бы, чтобы каждый процесс знал о pid() каждого из других процессов, с которыми он будет взаимодействовать. Сохраняйте [pid()] в состоянии процесса и поддерживайте его в актуальном состоянии, используя link/1, чтобы получить {'EXIT', Pid, ​​Reason}, когда процесс умирает.

person Vance Shipley    schedule 17.10.2012
comment
состояние процесса! это то же самое, что и словарь процесса? - person user1748906; 17.10.2012
comment
В функциональном программировании мы передаем в качестве аргументов данные, которые необходимы функции. Аргумент основного цикла может поддерживать данные о состоянии процесса. С поведением OTP gen_server и gen_fsm есть аргумент State для всех функций, которые вы используете для хранения данных о состоянии процесса. - person Vance Shipley; 05.11.2012