OTP расшифровывается как Open Telecom Platform; так исторически сложилось, потому что платформа создавалась для нужд и на деньги Ericsson. Но, в принципе, это название имеет примерно столько же коннотаций с ее функциональностью, сколько и яблоки со среднего качества телефонами. Основной отличительной характеристикой OTP по замыслу авторов является отказоустойчивость. Не многопоточность, не модель акторов, не богатые возможности pattern matching’а, даже не прозрачная кластеризация и не hot code upgrades. Отказоустойчивость. Виртуальная машина эрланга на поверхностный взгляд устроена очень просто: есть куча «процессов» (не системных процессов, эрланг-процессов) с изолированной памятью, которые могут обмениваться сообщениями. Все. Вот, что говорил Джо Армстронг по этому поводу: Обмен сообщениями внутри OTP очень прост: один процесс посылает сообщение другому (или группе других процессов), синхронно, или асинхронно. Но для этого необходимо знать, кому эти сообщения посылать. То есть менеджером обмена выступает отправитель. Но что если мы хотим просто слать broadcast и дать возможность всем заинтересованным процессам подписаться на это сообщение? Да, это обычный PubSub, но из коробки в OTP он не реализован. Ну да не беда, все кирпичики для того, чтобы за часик воплотить его на коленке у нас есть. Приступим. В принципе, Elixir включает модуль Registry, который может быть использован как scaffold для pubsub. Немного домотканного кода, аккуратный присмотр за всеми участниками (супервизор для каждого), — и все готово. Единственная проблема — Registry локален и не умеет в кластеризацию. То есть в распределенной среде (distributed nodes) эта красота работать не будет. На нашу удачу, есть и распределенная реализация Phoenix.PubSub, которая поставляется с двумя готовыми реализациями: Phoenix.PubSub.PG2 и Phoenix.PubSub.Redis. Ну, Redis — это явно лишнее звено в нашей цепочке, а вот PG2, работающий поверх эрланговских групп процессов pg2 — самое оно. Тоже, правда, без boilerplate не обойдется. Итак, у нас есть все, чтобы наладить удобные PubSub подписки в нашем приложении. Пора открывать текстовый редактор? — Не совсем. Я не люблю дублировать код из проекта в проект и все, что я могу вычленить в библиотеку — обособляется для повторного использования. Таким образом родился пакет Envío. Поскольку, болтовня, как известно, гроша выломанного не сто́ит, начнем с примеров использования.  Вот, в общем-то, и все. Осталось запихнуть MyApp.Sub в наше дерево супервизоров, и этот процесс начнет получать все сообщения, высланные при помощи функций из MyApp.Pub, который тоже не перегружен кодом. Для распределенных систем, состоящих из множества узлов, такой способ не подойдет. Нам нужно уметь подписываться на сообщения от других узлов, и Registry тут не помощник. Зато есть PG2, реализующий то же behaviour. Единственное отличие от автономного кода выше — manager: :phoenix_pub_sub параметр, который мы передаем в use Envio.Subscriber (и use Envio.Publisher), чтобы построить модуль на основе :pg2 вместо локального Registry. Теперь сообщения, отправленные с помощью такого Publisher будут доступны на всех узлах в кластере. Envío поддерживает так называемые backends. В поставке идет Envio.Slack, который позволяет донельзя упростить отсылку сообщений в Slack. Все, что требуется от приложения — отправить сообщение в канал, сконфигурированный в файле config/prod.exs — все остальное сделает Envío. Вот пример конфигурации: Теперь все сообщения, отправленные при помощи вызова MyApp.Pub.publish(:slack, %{foo: :bar}) будут доставлены в соответствующий канал в Slack, красиво отформатированные. Для того, чтобы перестать слать сообщения в Slack, достаточно остановить процесс Envio.Slack. Больше примеров (например, лог в IO) можно найти в тестах. Да чего я распинаюсь, попробуйте сами. Удачного сообщательства! Principal Engineer