Заметки на полях: Изучай Erlang во имя добра!
Фред Хеберт - широко известный в Erlang сообществе программист. Он не только написал дюжину полезных утилит и приложений, но и замечательную книгу “Изучай Erlang во имя добра!”, которая, к тому же, доступна онлайн совершенно бесплатно. Она в основном предназначена для тех, кто только начинает изучать Erlang. Но и более опытные разработчики с большой вероятностью найдут что-то новое в последних главах книги (CommonTest, Mnesia, Distributed Erlang).

Изучай Erlang во имя добра!
Вот лишь часть того, что я почерпнул из данной книги:
- используйте ctrl-a / ctrl-e в командной строке для перехода в начало / конец строки;
- ;(,) и andalso(orelse) различаются в работе при построении защитных выражений (guards). Например,
when C1 ; C2
не упадет с ошибкой, если первое условие (C1) покрашится, а вычислит второе (C2); - старайтесь избегать “true" веток в условных операторах, если есть возможность покрыть все варианты (пример:
X >= 0, X < 0
); - Björn Gustavsson из команды Erlang OTP рекомендует использовать gb_sets почти во всех случаях, ordsets, когда вам нужно простое представление и sets, когда требуется строгое сравнение =:= ;
- references используются, в том числе, потому что Pid может поменяться пока мы дожидаемся ответа на сообщение (процесс упал и был перезапущен супервизором);
- [ETS] ordered_set проигрывает по скорости рандомного чтения set, поэтому должен использоваться только для range queries;
- [EUnit]
?_assert
исполняется не сразу, а после генерации теста.
Симметричная мультипроцессорность появилась в Erlang не сразу, а была добавлена в 2000 годах (ее можно отключить с помощью
erl -smp disable
)
Distributed Erlang
- узлы в Erlang общаются по TCP соединению, и, если у вас большое сообщение, остальные сообщения будут ждать очень долго. Хуже того, heartbeat сообщения могут не дойти до узла и Erlang посчитает, что узел умер;
- большое количество связей (link) между узлами не есть хорошо, так как приведет к всплеску количества сообщений при падении одного из них;
- 4369 порт закреплен за epmd. range для портов узлов можно установить через inet_dist_listen_min(max);
- в консоли можно использовать net_kernel:connect для связи с узлом;
- {global, Name} медленно разрешает конфликты имен (3 стратегии) и потерю связи с узлами. Он подходит для небольшого количества регистраций, которые нечасто меняются с течением времени;
- распределенные приложения OTP (OTP Distributed Applications) делают упор на то, что ошибки в основном происходят по вине аппаратного обеспечения, а не разделения сети. Если у вас по другому - OTP не для вас. Они (приложения) служат для организации failover и backover;
- если планируется использовать горячую замену кода (hot code reloading), то записи (records) лучше не выставлять наружу (только в рамках модуля). Иначе - боль.
Версии Erlang >= R15B01 позволяют использовать реестры помимо local и global - {via, МодульРеестра, Имя}
Mnesia
- хорошей идеей будет добавить префикс к названию таблиц в mnesia (так как они шарятся по всему кластеру);
- при написании большого приложения лучше разделить логику приложения и код mnesia (чтобы, к примеру, иметь возможность заменить транзакции на синхронные);
- tv:start() - GUI для просмотра таблиц.
Полезные ссылки: