Erlang на практика

Малко теория

В последния урок разбрахме, че erlang стратегията е да разделя нишките на работници (работник) и система (надзорник) и да инструктира системните нишки да се справят със сривове на работни нишки.

Има научни трудове, които доказват, че значителна част от грешките в сървърните системи са причинени от временни условия и претоварването на част от системата в известно стабилно състояние ни позволява да се справим с тях. Сред такива произведения е докторската дисертация на Джо Армстронг, един от създателите на Erlang.

Препоръчително е да се изгради система на Erlang, така че всеки поток да е под надзора на надзорен орган, а самите надзорни органи да бъдат организирани в дърво.

Картината показва такова дърво. Възлите в него са надзорници, а листата са работни потоци. Падането на всеки поток и която и да е част от системата няма да остане незабелязано.

Дървото на надзора се разширява в началото на системата. Всеки ръководител е отговорен за стартиране на децата си, наблюдение на състоянието им, рестартиране и прекрасно прекратяване, ако е необходимо.

Erlang има стандартна реализация на супервизор. Той работи подобно на gen_server. Трябва да напишете персонализиран модул, който реализира поведението на надзорника, който включва една функция за обратно извикване init/1. От една страна, това е просто - само едно обратно обаждане. От друга страна в него трябва да върне доста сложна структура от данни, с която трябва да се работи правилно.

Стартирайте ръководител

Стартирането на супервизор е подобно на стартирането на gen_server. Ето снимка, подобна на тази, която видяхме в урок 10:

Нека ви напомня, че двата леви квадрата (отгоре и отдолу) съответстват на нашия модул. Двата десни квадрата съответстват на OTP кода. Горните два квадрата се изпълняват върху нишката на родителя, а двете долни квадратчета се изпълняват върху нишката на детето.

Нека започнем с функция start_link/0:

Тук молим ръководителя да започне нова тема.

Първи аргумент, -- това е името, под което да регистрирате потока. Има опция за надзор: start_link/2, в случай че не искаме да регистрираме поток.

Втори аргумент, ?МОДУЛ -- това е името на модула, чиито функции за обратно извикване ще извикат супервизор.

Третият аргумент е набор от параметри, които са необходими по време на инициализацията.

Тогава в червата на OTP се случва някаква магия, в резултат на което се създава поток от деца и се извиква обратно извикване init/1.

На init/1 трябва да върнете структура от данни, съдържаща цялата необходима информация за работата на надзорния орган.

Конфигурация на супервизор

Трябва да опишем спецификацията на самия супервизор и детето обработва, което той ще наблюдава.

Спецификацията на надзорник е набор от три стойности:

RestartStrategy описва политиката за рестартиране на дъщерни нишки. Има 4 опции за стратегия:

one_for_one -- когато една нишка падне, само тази нишка се рестартира, останалите продължават да работят.

един за всички -- когато една нишка се срине, всички дъщерни нишки се рестартират.

rest_for_one -- междинен вариант между първите две стратегии. Изводът е, че първоначално нишките се стартират една по една, в определена последователност. И когато една нишка се срине, тя се рестартира и тези нишки, които са стартирани по-късно. Тези, които бяха пуснати преди, продължават да работят.