Erlang
Erlang — це функціональна мова програмування і runtime-платформа для побудови concurrent, distributed і fault-tolerant систем.
Erlang створювався для телекомунікаційних систем, де важливі:
- висока доступність;
- обробка великої кількості одночасних з’єднань;
- відмовостійкість;
- гаряче оновлення коду;
- розподілена робота;
- ізоляція помилок;
- робота 24/7.
Сьогодні Erlang використовується не тільки в telecom, а й у messaging systems, real-time backend, distributed systems, IoT, фінансових системах, chat-серверах, брокерах повідомлень і high-availability інфраструктурі.
Коротко: Erlang — це мова й платформа для систем, які мають не просто “працювати”, а продовжувати працювати навіть тоді, коли окремі частини падають.
Офіційна сторінка Erlang пояснює, що OTP — це набір Erlang libraries і design principles для middleware, distributed database, взаємодії з іншими мовами, debugging і release handling tools. [1]
Головна ідея
Головна ідея Erlang — будувати системи з багатьох легких ізольованих процесів, які спілкуються повідомленнями.
Замість того щоб боятися кожної помилки, Erlang пропонує підхід:
Let it crash
Це не означає “писати поганий код”. Це означає: якщо процес потрапив у неправильний стан, краще дати йому впасти, а supervisor перезапустить його в чистому стані.
Проста аналогія: Erlang-система схожа на добре організовану команду. Якщо один працівник помилився, керівник не зупиняє всю компанію, а перезапускає саме цю ділянку роботи.
Актуальна версія
Станом на травень 2026 року офіційна сторінка Downloads вказує Erlang/OTP 28.5 як latest version of Erlang/OTP. [2]
Erlang/OTP 28 був випущений 21 травня 2025 року як новий major release з новими можливостями, покращеннями й деякими несумісностями. [3]
Серед помітних новинок OTP 28 офіційний блог виділяє priority messages — opt-in механізм, який дозволяє процесу отримувати деякі urgent messages раніше за звичайні повідомлення в черзі. [4]
Для документації: в Erlang важливо вказувати не просто “Erlang”, а конкретну версію Erlang/OTP: наприклад, OTP 28.5. Поведінка runtime, libraries і tooling може залежати від OTP-релізу.
Erlang і OTP
Erlang — це мова програмування.
OTP — це набір libraries, behaviours, design principles і tooling для побудови production-систем на Erlang.
OTP включає:
- supervisors;
- gen_server;
- gen_statem;
- applications;
- releases;
- logging;
- distributed tools;
- release handling;
- debugging tools;
- стандартні design patterns.
Тому часто говорять не просто Erlang, а Erlang/OTP.
BEAM VM
BEAM — virtual machine, на якій виконується Erlang-код.
BEAM також виконує інші мови, зокрема Elixir.
BEAM сильна в:
- lightweight processes;
- scheduling;
- message passing;
- fault isolation;
- concurrency;
- soft real-time behaviour;
- garbage collection per process;
- distributed Erlang;
- hot code loading.
BEAM — одна з головних причин, чому Erlang добре підходить для high-concurrency systems.
Actor model
Erlang часто описують через actor model.
У такому підході система складається з незалежних actors/processes.
Кожен process:
- має власний стан;
- не ділить пам’ять напряму;
- отримує messages;
- обробляє messages послідовно;
- може створювати інші processes;
- може падати незалежно від інших.
Це сильно відрізняється від shared-memory threading.
Lightweight processes
Erlang processes — це не операційні системні процеси.
Це легкі процеси всередині BEAM.
Можна створювати тисячі або мільйони Erlang processes, залежно від задачі й ресурсів.
Приклад створення process:
Pid = spawn(fun() ->
io:format("Hello from process~n")
end).
Process має PID — ідентифікатор процесу.
Message passing
Erlang processes спілкуються через messages.
Відправка повідомлення:
Pid ! {hello, "Erlang"}.
Отримання:
receive
{hello, Name} ->
io:format("Hello, ~s~n", [Name])
end.
Message passing допомагає уникати shared mutable state.
Ключова ідея: Erlang не намагається зробити один процес дуже складним. Він дозволяє створити багато маленьких процесів, які спілкуються повідомленнями.
Mailbox
Кожен Erlang process має mailbox — чергу повідомлень.
Коли process отримує message, він може обробити його через receive.
Якщо message не підходить під pattern, він залишається в mailbox.
Це дає гнучкість, але може створити проблему, якщо mailbox росте швидше, ніж process обробляє повідомлення.
Priority messages
У OTP 28 з’явилися priority messages.
Звичайно повідомлення додаються в кінець черги процесу. Priority messages — opt-in механізм, який дозволяє process отримувати певні urgent messages раніше, якщо receiver це підтримує. [5]
Це корисно для систем, де деякі control messages не повинні довго чекати за великою чергою звичайних повідомлень.
Pattern matching
Pattern matching — центральна частина Erlang.
Приклад:
{ok, Value} = {ok, 42}.
Якщо pattern не збігається, буде error.
У function clauses:
status_text(draft) -> "Чернетка"; status_text(paid) -> "Оплачено"; status_text(cancelled) -> "Скасовано".
Pattern matching робить обробку повідомлень і структур дуже природною.
Immutability
Дані в Erlang immutable.
Значення не змінюються після створення.
Наприклад:
X = 10, Y = X + 5.
X не змінюється. Створюється нове значення Y.
Immutability допомагає:
- уникати race conditions;
- спростити reasoning;
- зробити процеси ізольованими;
- краще працювати з message passing.
Functional programming
Erlang — функціональна мова.
Вона підтримує:
- functions;
- recursion;
- pattern matching;
- immutable data;
- higher-order functions;
- lists;
- tuples;
- maps;
- anonymous functions;
- tail recursion.
Але Erlang дуже практичний: його функціональність служить не академічній красі, а побудові надійних систем.
Variables
Змінні в Erlang присвоюються один раз.
Приклад:
Name = "Erlang".
Спроба присвоїти інше значення тій самій змінній не працює як у імперативних мовах.
Це називають single assignment.
Atoms
Atom — іменоване константне значення.
Приклади:
ok error draft paid cancelled
Atoms часто використовують для status, tags, messages і pattern matching.
Важливо: atoms не збираються garbage collector у звичайному сенсі, тому не можна безконтрольно створювати atoms із зовнішнього input.
Tuples
Tuple — фіксована структура.
Приклад:
{ok, 42}
{error, not_found}
{customer, 10, "Anna"}
У Erlang дуже поширений стиль:
{ok, Result}
{error, Reason}
Це дозволяє явно обробляти успіх і помилку.
Lists
List — базова структура даних.
Приклад:
Numbers = [1, 2, 3, 4].
Pattern matching зі списком:
[Head | Tail] = [1, 2, 3].
Тут:
Headбуде1;Tailбуде[2,3].
Maps
Map — key-value структура.
Приклад:
User = #{id => 1, name => <<"Anna">>, active => true}.
Доступ:
Name = maps:get(name, User).
Maps корисні для structured data, configs, JSON-like structures і API payloads.
Records
Records — старіший спосіб описати structured data.
Приклад:
-record(customer, {
id,
name,
email
}).
Використання:
Customer = #customer{id = 1, name = "Anna"}.
Records часто зустрічаються в старому Erlang-коді.
Binaries
Binaries використовуються для bytes і binary data.
Приклад:
Data = <<"hello">>.
Binaries важливі для:
- network protocols;
- files;
- binary formats;
- strings as UTF-8 binaries;
- performance-sensitive data processing;
- messaging.
Erlang має потужний binary pattern matching:
<<A:8, B:8, Rest/binary>> = Data.
Strings
Історично string в Erlang — це list of integers.
Приклад:
"hello"
Але для сучасної роботи з текстом і network data часто використовують binaries:
<<"hello">>
Треба розуміти різницю між lists і binaries, бо вона впливає на performance і APIs.
Recursion
Erlang не має класичних loops як у багатьох імперативних мовах.
Замість цього використовується recursion.
Приклад:
sum([]) -> 0; sum([H | T]) -> H + sum(T).
Для довгих циклів важлива tail recursion.
Tail recursion
Tail recursion — recursion, де recursive call є останньою операцією функції.
Приклад:
sum(List) ->
sum(List, 0).
sum([], Acc) ->
Acc;
sum([H | T], Acc) ->
sum(T, Acc + H).
Tail recursion дозволяє runtime оптимізувати стек.
Modules
Erlang-код організовано в modules.
Приклад:
-module(example).
-export([hello/0]).
hello() ->
io:format("Hello~n").
Module має ім’я й список exported functions.
Функції ідентифікуються як:
module:function/arity
Наприклад:
example:hello/0
Function arity
Arity — кількість аргументів функції.
У Erlang foo/1 і foo/2 — різні функції.
Приклад:
add(A) -> A + 1. add(A, B) -> A + B.
Це важливо для exports, callbacks і documentation.
Behaviours
Behaviour — OTP-шаблон для типових процесів.
Основні behaviours:
- gen_server;
- gen_statem;
- gen_event;
- supervisor;
- application.
Behaviour визначає callback functions, які module має реалізувати.
Це дає стандартну структуру для production-процесів.
gen_server
gen_server — generic server behaviour.
Він використовується для процесів, які мають state і обробляють requests/messages.
Офіційна документація gen_server пояснює, що gen_server може створювати process як частину supervision tree через start_link, а process викликає Module:init/1 для ініціалізації. [6]
Типові callbacks:
- init/1;
- handle_call/3;
- handle_cast/2;
- handle_info/2;
- terminate/2;
- code_change/3.
call і cast
У gen_server є два типові способи взаємодії:
call— синхронний request із відповіддю;cast— асинхронне повідомлення без очікування відповіді.
Приклад ідеї:
gen_server:call(Server, get_state).
gen_server:cast(Server, {set_value, 42}).
call зручно використовувати, коли потрібна відповідь.
cast — коли потрібно просто надіслати команду.
gen_statem
gen_statem — behaviour для state machines.
Він корисний, коли процес має чіткі стани й переходи між ними.
Сценарії:
- protocols;
- connection lifecycle;
- payment workflow;
- device states;
- session management;
- telecom flows.
gen_statem часто кращий за gen_server, коли логіка справді є state machine.
supervisor
Supervisor — процес, який контролює child processes.
Офіційна документація supervisor behavior описує supervisor як process, що supervises child processes; child process може бути іншим supervisor або worker process, зазвичай реалізованим через gen_server, gen_statem або gen_event. [7]
Supervisor може перезапускати child process, якщо той падає.
Supervision tree
Supervision tree — дерево supervisors і workers.
Приклад ідеї:
Application Supervisor
├── Database Worker
├── HTTP Listener
└── Session Supervisor
├── Session Worker 1
├── Session Worker 2
└── Session Worker 3
Supervision tree — основа Erlang fault tolerance.
Головна сила OTP: ви не просто пишете процеси. Ви описуєте, хто за ким стежить, що робити після падіння, як перезапускати частини системи й де проходять межі відмови.
Restart strategies
Supervisors мають restart strategies.
Типові стратегії:
- one_for_one;
- one_for_all;
- rest_for_one;
- simple_one_for_one historically / dynamic supervisors у новіших підходах.
Сенс:
- перезапустити тільки process, що впав;
- перезапустити всіх;
- перезапустити process і тих, хто залежить від нього.
Вибір restart strategy — важлива архітектурна частина.
Let it crash
Let it crash — філософія Erlang.
Ідея:
- не ловити кожну помилку локально;
- не залишати процес у невідомому стані;
- дати процесу впасти;
- supervisor перезапустить його;
- система продовжить працювати.
Цей підхід працює тільки тоді, коли правильно побудовані supervision trees, state boundaries і recovery strategy.
Fault tolerance
Fault tolerance — здатність системи продовжувати роботу після часткових помилок.
Erlang допомагає через:
- isolated processes;
- supervisors;
- links;
- monitors;
- message passing;
- supervision trees;
- crash recovery;
- distribution;
- process-per-connection style;
- hot code loading.
Але fault tolerance не виникає автоматично. Її потрібно проектувати.
Links і monitors
Processes можуть бути linked або monitored.
Link створює двосторонній зв’язок: якщо один process падає, сигнал отримує інший.
Monitor дозволяє одному process спостерігати за іншим без взаємного зв’язку.
Це основа для supervisor-like behaviour і fault detection.
Applications
OTP application — логічна одиниця Erlang-системи.
Application може мати:
- application callback module;
- supervision tree;
- config;
- dependencies;
- workers;
- release metadata.
OTP application — не обов’язково “додаток” у звичному UI-сенсі. Це компонент системи.
Releases
Erlang release — зібрана система для deployment.
Release може включати:
- Erlang runtime;
- applications;
- configuration;
- boot scripts;
- release metadata;
- versioning;
- upgrade instructions.
Releases важливі для production, бо Erlang-система часто складається з багатьох OTP applications.
Hot code upgrade
Erlang підтримує hot code loading і hot upgrade.
Ідея: можна оновити код без повної зупинки системи.
Це важливо для telecom і high-availability systems.
Але hot upgrades складні:
- потрібно думати про state migration;
- old і new code можуть співіснувати;
- callbacks code_change/3 мають бути правильними;
- release handling має бути протестований.
У багатьох сучасних deployment-процесах замість hot upgrade використовують rolling deploy або blue-green deploy, але сама можливість залишається важливою частиною Erlang-історії.
Distributed Erlang
Distributed Erlang дозволяє Erlang nodes спілкуватися між собою.
Node може надсилати messages process на іншому node майже так само, як локальному process.
Це зручно для distributed systems, але потребує обережності:
- network partitions;
- security;
- node cookies;
- latency;
- cluster topology;
- observability;
- failure detection.
Node cookie
Erlang nodes використовують cookie для автентифікації між nodes.
Якщо cookies не збігаються, nodes не з’єднаються.
Cookie потрібно зберігати як секрет.
Не можна випадково публікувати Erlang cookie в репозиторії або logs.
Mnesia
Mnesia — distributed database management system, що входить в OTP.
Вона історично корисна для Erlang-систем, але її потрібно використовувати обережно.
Mnesia може бути доречною для:
- distributed Erlang applications;
- metadata;
- telecom-like systems;
- small/medium distributed state;
- systems tightly integrated with Erlang nodes.
Для багатьох сучасних web/backend систем частіше використовують PostgreSQL, Redis, Kafka, RabbitMQ або інші спеціалізовані сховища.
ETS
ETS — Erlang Term Storage.
ETS — in-memory tables для зберігання Erlang terms.
ETS корисний для:
- caches;
- lookup tables;
- shared read-heavy data;
- session data;
- counters;
- local state.
ETS не є заміною persistent database, але дуже корисний для runtime state.
DETS
DETS — disk-based term storage.
DETS схожий на disk-based варіант ETS, але має інші обмеження й performance characteristics.
Для production persistence потрібно обережно оцінювати, чи DETS справді підходить.
Ports і NIFs
Erlang може взаємодіяти з зовнішнім кодом через ports і NIFs.
Port — безпечніший спосіб спілкування із зовнішньою програмою як окремим OS process.
NIF — Native Implemented Function, код на C/C++, який викликається всередині BEAM.
NIF може бути швидким, але небезпечним: поганий NIF може заблокувати або зламати VM.
Важливо: NIF — це місце, де Erlang може втратити частину своєї fault tolerance. Помилка в native code може вплинути на всю VM, а не лише на один Erlang process.
Синтаксис Erlang
Приклад модуля:
-module(greeter).
-export([hello/1]).
hello(Name) ->
io:format("Hello, ~s~n", [Name]).
Компіляція в shell:
c(greeter).
greeter:hello("Erlang").
Erlang syntax може здаватися незвичним через:
- крапки в кінці function definitions;
- коми між expressions;
- крапку з комою між clauses;
- atoms;
- pattern matching;
- single assignment.
Erlang shell
Erlang shell запускається командою:
erl
Приклад:
1> 2 + 3. 5 2> self(). <0.82.0>
Shell корисний для:
- навчання;
- testing small functions;
- process experiments;
- debugging;
- runtime inspection.
Rebar3
rebar3 — популярний build tool для Erlang.
Він використовується для:
- створення проєктів;
- builds;
- tests;
- dependencies;
- releases;
- plugins;
- Common Test;
- Dialyzer integration.
Типові команди:
rebar3 new app my_app rebar3 compile rebar3 eunit rebar3 ct rebar3 release
Rebar3 — стандартний вибір для багатьох Erlang-проєктів.
Hex.pm
Hex.pm — package manager ecosystem для Erlang/Elixir.
Використовується для dependencies.
Перед додаванням dependency потрібно перевіряти:
- підтримку;
- ліцензію;
- сумісність з OTP;
- активність;
- транзитивні залежності;
- security issues.
Dialyzer
Dialyzer — static analysis tool для Erlang.
Він знаходить:
- type discrepancies;
- unreachable code;
- pattern matching issues;
- potential bugs.
Dialyzer використовує success typing, а не класичну повну статичну типізацію.
Це означає, що він часто знаходить реальні проблеми, але не вимагає описувати всі типи наперед.
Typespecs
Erlang підтримує typespecs.
Приклад:
-spec add(integer(), integer()) -> integer().
add(A, B) ->
A + B.
Typespecs корисні для:
- документації;
- Dialyzer;
- API contracts;
- code navigation;
- maintenance.
EUnit
EUnit — unit testing framework для Erlang.
Приклад:
add_test() ->
?assertEqual(5, add(2, 3)).
EUnit корисний для маленьких unit tests.
Common Test
Common Test — testing framework для більших test suites.
Він корисний для:
- integration tests;
- system tests;
- protocol tests;
- distributed tests;
- telecom-style testing;
- complex setup/teardown.
Common Test часто використовується в серйозних Erlang/OTP проєктах.
PropEr
PropEr — property-based testing tool для Erlang.
Property-based testing перевіряє не один приклад, а властивості програми на багатьох generated inputs.
Це добре підходить для:
- protocols;
- parsers;
- state machines;
- business rules;
- serialization;
- distributed logic.
Erlang і Elixir
Elixir — сучасна мова на BEAM VM.
Вона використовує Erlang/OTP ecosystem, але має інший синтаксис і tooling.
Порівняння:
| Мова | Особливість |
|---|---|
| Erlang | оригінальна мова OTP, telecom roots, дуже стабільна |
| Elixir | сучасніший синтаксис, Mix tooling, Phoenix web framework, ширша популярність у web |
Elixir не замінює Erlang повністю. Багато core libraries і OTP написані Erlang.
Erlang і RabbitMQ
RabbitMQ — популярний message broker, написаний на Erlang.
Це один із найвідоміших прикладів практичного використання Erlang/OTP.
RabbitMQ використовує сильні сторони Erlang:
- concurrency;
- fault tolerance;
- process isolation;
- distributed behaviour;
- message-oriented architecture.
Erlang і WhatsApp
WhatsApp історично часто згадується як приклад системи, яка використовувала Erlang для масштабної messaging infrastructure.
Цей приклад важливий не як “магічна реклама Erlang”, а як демонстрація того, що Erlang добре підходить для великої кількості одночасних з’єднань і messaging.
Erlang і telecom
Erlang народився в telecom.
Telecom systems потребували:
- 24/7 availability;
- soft real-time;
- hot upgrade;
- fault isolation;
- distributed operation;
- call/session management;
- supervision;
- message passing.
Саме ці вимоги сформували Erlang/OTP.
Soft real-time
Soft real-time означає, що система має реагувати швидко й стабільно, але не гарантує жорстких real-time deadlines як hard real-time systems.
Erlang добре підходить для soft real-time:
- messaging;
- telecom sessions;
- chat;
- presence;
- notification systems;
- control planes.
Але для hard real-time embedded control Erlang зазвичай не є першим вибором.
Erlang у backend
Erlang можна використовувати для backend-сервісів.
Сценарії:
- messaging backend;
- chat server;
- presence system;
- notification service;
- IoT gateway;
- protocol server;
- multiplayer coordination;
- distributed control plane;
- queue workers;
- real-time systems.
Для класичного CRUD API Erlang теж можливий, але часто Elixir/Phoenix або інші мови можуть бути зручнішими для команди.
Erlang і Web
Erlang має web libraries/frameworks:
- Cowboy;
- Ranch;
- Elli;
- Webmachine historically;
- Zotonic;
- ChicagoBoss historically.
Cowboy часто використовується для HTTP/WebSocket servers.
Erlang web stack менш mainstream, ніж Node.js, Python, Go, Java або C#, але сильний у concurrent connection handling.
Erlang і distributed systems
Erlang добре підходить для distributed systems, але не робить їх автоматично простими.
Потрібно думати про:
- network partitions;
- consistency;
- message ordering;
- retries;
- duplicate messages;
- idempotency;
- cluster membership;
- observability;
- backpressure;
- failure domains.
Erlang дає інструменти, але архітектурні проблеми distributed systems залишаються.
Backpressure
Backpressure — механізм, який не дозволяє producer надсилати більше повідомлень, ніж consumer може обробити.
В Erlang backpressure важливий, бо mailbox process може рости.
Без backpressure можливі:
- memory growth;
- latency;
- process overload;
- node instability.
Потрібно проектувати flow control.
Observability
Для Erlang production-систем потрібні:
- logs;
- metrics;
- tracing;
- process inspection;
- crash reports;
- supervision tree visibility;
- mailbox length monitoring;
- memory monitoring;
- scheduler utilization;
- distributed node health.
Інструменти можуть включати:
- observer;
- recon;
- telemetry;
- OpenTelemetry;
- logs;
- custom metrics;
- VM statistics.
Observer
Observer — Erlang GUI tool для перегляду runtime-системи.
Він може показувати:
- processes;
- applications;
- memory;
- scheduler info;
- ETS tables;
- supervision trees.
Observer корисний для локального аналізу й debugging.
Performance
Erlang оптимізований для concurrency і availability, а не для raw CPU performance у стилі C/Rust.
На performance впливають:
- кількість processes;
- mailbox sizes;
- message copying;
- binary handling;
- scheduler utilization;
- garbage collection;
- ETS usage;
- NIFs;
- distribution overhead;
- serialization;
- supervision restarts.
Для CPU-heavy задач Erlang може бути не найкращим вибором.
Для high-concurrency I/O systems — часто дуже сильний.
Garbage collection
У BEAM garbage collection зазвичай process-local.
Це допомагає ізолювати паузи: GC одного process не мусить зупиняти всю VM.
Це одна з причин, чому Erlang добре підходить для систем із багатьма одночасними процесами.
Безпека
Erlang-системи потребують безпеки так само, як інші backend-системи.
Потрібно контролювати:
- distributed Erlang cookie;
- TLS;
- input validation;
- authentication;
- authorization;
- secrets;
- dependency security;
- NIF risks;
- exposed ports;
- node connectivity;
- logging;
- remote shell access;
- configuration;
- cluster access.
Особливо уважно потрібно ставитися до distributed Erlang у відкритих мережах.
Erlang cookie security
Erlang cookie — секрет для node communication.
Не можна:
- комітити cookie в Git;
- використовувати однаковий cookie для всіх середовищ;
- писати cookie в logs;
- відкривати distributed Erlang ports у публічний інтернет без захисту.
Для production потрібні network isolation, firewall, secrets management і TLS, якщо доречно.
Erlang і Python / Go / Java / C#
Порівняння:
| Мова | Сильні сторони |
|---|---|
| Erlang | fault tolerance, concurrency, messaging, distributed systems, OTP |
| Go | простий backend, cloud-native, single binary, performance |
| Java | enterprise ecosystem, JVM, Spring, tooling |
| C# | .NET, ASP.NET Core, Microsoft ecosystem, enterprise |
| Python | scripting, data, AI, automation, швидкий старт |
Erlang найсильніший там, де потрібні concurrency, fault tolerance і long-running systems.
Erlang і Haskell
Erlang і Haskell обидві функціональні, але мають різну філософію.
| Мова | Фокус |
|---|---|
| Erlang | fault-tolerant distributed runtime, processes, message passing, OTP |
| Haskell | чисті функції, сильна type system, lazy evaluation, математичне моделювання |
Erlang практичніший для resilient runtime systems.
Haskell сильніший у type-driven correctness і pure functional modeling.
Erlang у бізнесі
Erlang може бути корисним у бізнесі, якщо потрібні:
- messaging;
- telecom;
- real-time backend;
- high availability;
- distributed systems;
- IoT gateways;
- notification services;
- chat;
- queue systems;
- fault-tolerant services;
- systems that run 24/7.
Але Erlang має менший ринок розробників, ніж mainstream backend-мови.
Erlang і ERP-системи
Erlang не є ERP-системою.
Він не веде облік, не проводить документи й не керує складом сам по собі.
У контексті K2 ERP Erlang може бути корисним опосередковано:
- message broker integration;
- real-time notification service;
- high-availability gateway;
- concurrent session service;
- IoT/telemetry ingestion;
- distributed background processing;
- fault-tolerant integration layer;
- service, де важлива supervision і self-healing.
Але основну бізнес-логіку ERP зазвичай варто писати в основному стеку системи. Erlang доречний тоді, коли його fault-tolerance модель справді потрібна.
Erlang і API
Erlang може створювати HTTP API через Cowboy або інші libraries.
Приклад сценарію:
- HTTP listener приймає request;
- process обробляє session;
- gen_server керує state;
- supervisor перезапускає workers;
- response повертається client.
Erlang API особливо доречні, коли багато одночасних connections або WebSocket sessions.
Erlang і тестування коду
Для тестування коду в Erlang варто поєднувати:
- EUnit для unit tests;
- Common Test для integration/system tests;
- PropEr для property-based tests;
- Dialyzer для static analysis;
- release tests;
- distributed tests;
- fault injection;
- supervisor restart tests.
Для fault-tolerant систем важливо тестувати не тільки “happy path”, а й падіння processes, timeouts, повтори й network issues.
Коли Erlang особливо корисний
Erlang особливо корисний для:
- telecom;
- messaging;
- chat;
- notification systems;
- real-time backend;
- distributed systems;
- high-availability services;
- fault-tolerant systems;
- process-per-connection architectures;
- protocol servers;
- RabbitMQ-like systems;
- IoT gateways;
- systems that must run continuously.
Коли Erlang може бути невдалим вибором
Erlang може бути невдалим вибором, якщо:
- потрібен простий CRUD;
- команда не знає Erlang/OTP;
- потрібен великий ринок розробників;
- потрібен CPU-heavy numerical code;
- потрібна AI/data science ecosystem;
- потрібен mobile app;
- потрібен modern mainstream web stack;
- fault tolerance не є важливою вимогою;
- система легко вирішується Go/C#/Java/Python;
- немає плану observability і OTP architecture.
Типові помилки в Erlang
Поширені помилки:
- писати Erlang як імперативну мову;
- створювати processes без supervision;
- ігнорувати mailbox growth;
- використовувати gen_server для всього;
- ловити всі errors замість правильної supervision strategy;
- створювати atoms із зовнішнього input;
- використовувати NIF без розуміння ризиків;
- не контролювати distributed Erlang security;
- не тестувати restart scenarios;
- не використовувати Dialyzer;
- не документувати message formats;
- не думати про backpressure;
- запускати distributed nodes без network/security design.
Хороші практики
Під час роботи з Erlang варто:
- Проектувати supervision tree з самого початку.
- Використовувати OTP behaviours.
- Не створювати процеси без зрозумілого lifecycle.
- Стежити за mailbox length.
- Описувати message formats.
- Не створювати atoms із user input.
- Використовувати gen_server для stateful servers, але не для всього.
- Використовувати gen_statem для state machines.
- Додавати EUnit і Common Test.
- Використовувати Dialyzer і typespecs.
- Тестувати crash/restart scenarios.
- Думати про backpressure.
- Захищати Erlang cookie.
- Обережно використовувати NIFs.
- Моніторити BEAM runtime metrics.
Практичний висновок
Erlang — це не просто функціональна мова. Це платформа для побудови систем, які мають жити довго, обробляти багато одночасних подій і відновлюватися після помилок.
Сильні сторони:
- BEAM VM;
- lightweight processes;
- message passing;
- actor model;
- OTP;
- supervisors;
- supervision trees;
- gen_server;
- gen_statem;
- fault tolerance;
- distributed Erlang;
- hot code loading;
- telecom heritage;
- soft real-time systems;
- RabbitMQ-like workloads.
Обмеження:
- менший ринок розробників;
- незвичний синтаксис;
- менша mainstream web ecosystem;
- не найкращий вибір для CPU-heavy задач;
- distributed systems усе одно складні;
- потрібна дисципліна OTP architecture;
- NIFs можуть зламати fault tolerance;
- observability і backpressure потрібно проектувати.
Erlang найкраще використовувати там, де головна вимога — не просто виконати код, а побудувати систему, яка продовжує працювати під навантаженням, при помилках і в distributed environment.
Пояснення термінів
- Erlang — функціональна мова й runtime-платформа для concurrent і fault-tolerant systems.
- OTP — набір Erlang libraries, behaviours і design principles для production systems.
- BEAM — virtual machine для Erlang і Elixir.
- Actor model — модель, де незалежні actors/processes спілкуються messages.
- Process — легкий Erlang process у BEAM, не OS process.
- PID — process identifier.
- Message passing — передача повідомлень між processes.
- Mailbox — черга повідомлень процесу.
- Priority messages — механізм OTP 28 для пріоритетних повідомлень.
- Pattern matching — зіставлення значень із шаблонами.
- Atom — іменована константа.
- Tuple — фіксована структура значень.
- Map — key-value структура.
- Binary — binary data у Erlang.
- Arity — кількість аргументів функції.
- Behaviour — OTP-шаблон із callbacks.
- gen_server — generic server behaviour.
- gen_statem — behaviour для state machines.
- Supervisor — process, що контролює child processes.
- Supervision tree — дерево supervisors і workers.
- Let it crash — філософія fault tolerance через контрольовані падіння й перезапуски.
- Application — OTP application, логічна одиниця системи.
- Release — зібрана Erlang/OTP-система для deployment.
- Hot code upgrade — оновлення коду без повної зупинки системи.
- Distributed Erlang — взаємодія Erlang nodes у distributed system.
- Mnesia — distributed database в OTP.
- ETS — in-memory storage для Erlang terms.
- NIF — Native Implemented Function.
- Dialyzer — static analysis tool для Erlang.
- EUnit — unit testing framework.
- Common Test — framework для більших test suites.
- PropEr — property-based testing tool.
- Rebar3 — build tool для Erlang.
- Hex.pm — package ecosystem для Erlang/Elixir.
Дивіться також
- Elixir
- Haskell
- Go
- C Sharp
- Python
- PowerShell
- Assembly
- Visual Basic
- MATLAB
- Розробка в K2 ERP
- Тестування коду
- API K2 ERP
- Інтеграції K2 ERP
- Retrieval-Augmented Generation
- Великі мовні моделі
- GitHub Copilot
- Cursor
- Tabnine
- Штучний інтелект
- Генеративний AI
Джерела
- Erlang/OTP — офіційна сторінка
- Erlang/OTP Downloads
- Erlang/OTP 28 Downloads
- Erlang/OTP 28.0 Release
- Erlang/OTP 28 Highlights
- Erlang/OTP Documentation
- Erlang/OTP — supervisor behaviour
- Erlang/OTP — gen_server Behaviour
- Erlang/OTP — gen_server manual
- Erlang/OTP — Supervisor Principles
- Erlang/OTP — Applications
- Erlang/OTP — Release Structure
- Erlang/OTP — Distributed Erlang
- Erlang/OTP GitHub Repository
- Erlang/OTP GitHub Releases
- Rebar3
- Erlang/OTP — EUnit
- Common Test
- PropEr
- Learn You Some Erlang
- MediaWiki — Help:Formatting
- MediaWiki — Help:Links