Skip to content

Материалы ко внутреннему митапу в FunBox, посвященному проблемам в коде новичков в Erlang/Elixir

Notifications You must be signed in to change notification settings

savonarola/elixir-basic-patterns

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Стиль

Говнокод

Условный пример: bad_looking_code.ex. Код, выглядящий так даже издалека, всегда плох. В нем:

  • смешаны разные уровни абстракции;
  • копипаста;
  • перегрузка обязанностей;
  • непрозрачное переопредееление переменных;
  • ...

В таком коде всегда будут плодиться ошибки.

Возврат Ok/Error

Возврат {:ok, ok_result} и {:error, error} -- это стандарт. Положительный и отрицательный результаты должны легко матчиться для возможности просто использовать эмуляцию монады Maybe или Either через with.

Примеры: error_return.ex.

Exceptions vs errors

Не стоит использовать Exceptions для контроля бизнес логики. Это усложняет тип функций, лишает возможности его описать.

Exceptions -- это возможность нормально сообщить, почему код все бросает и падает.

exceptions.ex

Dependency Injection

Два фетчера:

В первом изпользуемый HTTP клиент захардкожен, во втором передается.

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

Тест второго модуля специфицирует реальный контракт с модулем.

Dependency Injection времени

При работе с таймаутами лучше не использовать таймеры. Это сложный внешний state, за которым приходится следить и который трудно тестировать.

Для некритичных к идеальной точности таймеров удобно использовать tick, посылку текущего времени самому себе с указанным интервалом: rotating_file_writer.ex.

Тогда state таймеров превращается в обыкновенный конечный автомат, который легко тестировать извне.

Пример: smpp_timers.ex -- сложная композиция из четырех таймеров SMPP. В oserl реализована с багами через установку и отмену таймеров.

Простейшие паттерны/антипаттерны параллельности

  • Антипаттерн: синхронные операции в "общем" GenServer: good_fetcher.ex. При глобальном использовании представляет из себя бутылочное горлышко.
  • Антипаттерн: возможная неявная синхронизация во внешней либе (HTTPoison) даже при наличии пула. Бутылочное горлышко может быть спрятано и во внешней либе.

Организация последовательной обработки

  • chain_flow_procs.ex -- Плохо. Event кидается от процесса к процессу. Неконтролируемая нагрузка, низкая/неконтролируемая параллелность, неконтролируемая емкость системы.
  • chain_flow_funs.ex -- Не так плохо, но тоже плохо. Event кидается из функции в функцию, сложно отслеживать и расширять поток.
  • direct_flow.ex -- Хорошо. Свой поток выполнения для каждого Event'а, неважно, что из себя представляют обработчики, можно легко измерить статистику по каждой стадии обработки, легко управлять стадиями.

About

Материалы ко внутреннему митапу в FunBox, посвященному проблемам в коде новичков в Erlang/Elixir

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages