Отличие Erlang от объектных языков

3,826
-1

Published on

Чем erlang отличается от других объектных языков. Надежность, изоляция, асинхронные сообщения. Горячее обновление кода и прозрачная работа по сети.

Published in: Technology, News & Politics
0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,826
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
63
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide
























































  • Отличие Erlang от объектных языков

    1. 1. Erlang Макс Лапшин max@evilmartians.com http://erlyvideo.org/
    2. 2. Erlang
    3. 3. Erlang Был разработан в Ericsson инженерами, которым хотелось больше спать по ночам и не работать в выходные
    4. 4. Область применения • Сетевые сервисы
    5. 5. Область применения • Сетевые сервисы с постоянно подключенными клиентами
    6. 6. Что заменяет? • С++ • Java • Ruby • Perl
    7. 7. Что заменяет? • С++ • Java • Ruby • Perl • зоопарк из кучи программ, собранных на соплях шелл-скриптов и monit-а сбоку
    8. 8. ООП • Инкапсуляция • Наследование • Полиморфизм. Который на самом деле мономорфизм.
    9. 9. ООП • Инкапсуляция • Наследование • Полиморфизм. Который на самом деле мономорфизм. • Обработка ошибок • Распределенная работа
    10. 10. Цикл жизни объекта • Создание • Обработка метода • Смена состояния • п. 2 • Уничтожение
    11. 11. Erlang-овские процессы array(Data) -> NewData = perform_action(Data), array(NewData).
    12. 12. Классический вызов метода result = object.method(arg1, arg2);
    13. 13. Вызов — посылка сообщения Array ! {set, Index, Value}.
    14. 14. Прием метода эксплицитный array(Data) -> receive {set, Index, Value} -> array(set(Data,Index,Value)) end.
    15. 15. gen_server:call иммитация вызова метода gen_server:call(Array, {get, 3}).
    16. 16. Внутри вызывающего: Ref = make_ref(), Array ! {‘call’,self(),Ref,{get,4}}.
    17. 17. Внутри объекта: receive {‘call’,Pid,Ref,Call} -> Pid ! {Ref,handle(Call,State)}
    18. 18. Отложенный ответ receive {‘call’,Pid,Ref,Call} -> Result = handle(Call,State, ... Pid ! {Ref, Result}
    19. 19. «Объекты» • Вместо объектов процессы • Вместо ссылок — pid-ы • Вместо вызовов методов — посылка сообщений • «Методы» накапливаются — мейлбокс процесса
    20. 20. Синхронизация доступа к объектам array.set(array.length, value);
    21. 21. Синхронизация доступа к объектам mutex.lock(); array.set(array.length, value); mutex.unlock();
    22. 22. Синхронизация в Erlang • Вызовы методов синхронизированы в мейлбоксе процесса • Процессы нереентерабельны by-design
    23. 23. Инкапсуляция • Во всех классических языках можно добраться до переменной внутри объекта
    24. 24. Инкапсуляция • В Erlang процессы общаются только сообщениями • Данные и ошибки изолированы внутри процессов
    25. 25. Инкапсуляция • В Erlang процессы общаются только сообщениями • Данные и ошибки изолированы внутри процессов почти всегда: есть ets, dets и IO
    26. 26. Наследование • В erlang наследования нет • Есть композиция: gen_server, gen_fsm
    27. 27. Behaviour gen_server receive {‘call’, From, Call} -> Reply = M:handle_call(Call,State), reply(From,Reply); Else -> Module:handle_info(Else,State)
    28. 28. Behaviour gen_server gen_server.erl: start(Module, Args) -> State = Module:init(Args) our_module.erl: init(Args) -> ... handle_call(Call,State) -> ...
    29. 29. Полиморфизм • Процессы не имеют типов • Вся типизация duck-typing: процесс может отвечать на сообщение • По PID-у ничего про процесс не узнать (можно, но не стоит)
    30. 30. Обработка ошибок • Как локализовать ошибку? • Что делать, поймав её? • Как и кого наказать за ошибку?
    31. 31. Изоляция ошибок • Exceptions и ошибки живут только внутри процесса • Никаких проездов по стеку • valgrind можно убрать на полку
    32. 32. Let it crash • Стандартная практика — не обрабатывать ошибку {ok, File} = file:open(FileName, [read]) • Полагаться на каскадное завершение группы процессов
    33. 33. Время жизни объекта • GC коварен и недетерминирован • C++ и ObjectiveC дают контроль, но текут • Финализаторы образуют циклы и текут
    34. 34. Процесс завершается явно hash(Data) -> receive {set, Key, Value} -> hash(set(Key,Value,Data)); stop -> ok end.
    35. 35. Линки и мониторы • Один процесс получает сообщение о смерти другого erlang:monitor(process,Pid)
    36. 36. Монитор • реентерабелен • отменяется receive {‘DOWN’,Ref,process,Pid,Reason}
    37. 37. Ручной счетчик ссылок • Объект Client регистрируется у Server • при смерти Client, Server вычеркивает его из списка • после ухода последнего Client, Server сам решает как быть • кто ещё умеет удаляться с таймаутом?
    38. 38. Супервизоры • Специальные процессы, следящие за другими • Группы супервизоров объединяются в приложения • appmon:start()
    39. 39. RPC • Sun RPC • Corba • SOAP • и прочие ночные кошмары
    40. 40. Классические проблемы • Вызов удаленных методов • Передача сложных объектов • Распределенная сборка мусора • Обработка потери связности
    41. 41. RPC со встроенным Erlangом Array ! {append, Value}.
    42. 42. Прозрачная сеть • Посылка сообщений по сети прозрачна • Включая анонимные функции! Remote ! fun(S) -> S + 5 end; • Включая открытые файлы • И прочее-прочее
    43. 43. Мониторы по сети • Работают как обычные • К ним добавляется отдельный мониторинг нод
    44. 44. Глобальные переменные • Локальные erlang:register(rtmp_listener, Pid) rtmp_listener ! accept • Удаленные {‘ems@streamer2’,rtmp_listener} ! accept
    45. 45. Продакшн • Производительность • Слежение за ошибками • Перезапуск сбойных сервисов • Выкатывание обновлений
    46. 46. 10K+ пользователей • 10K пользователей нитками не обслужить • Нитки — минимум 2МБ памяти, фрагментированный стек • Нитки дорого • Есть epoll/kqueue
    47. 47. Evented • не надо писать код синхронизаций • epoll + threads — адское сочетание
    48. 48. erl -smp enable • Все данные в erlang немутабельны • Процесс легко мигрирует на другое ядро • Каждое ядро имеет свой шедулер • Линейное масштабирование по ядрам
    49. 49. Горячий апдейт кода • Классически решается рестартом сервера
    50. 50. В erlang апдейт из коробки • В момент tail call начинает выполняться новый код • Код приложения заливается по сети на другие ноды
    51. 51. Резюме • Решена проблема синхронизации доступа к объектам • Эффективно скрещен epoll/kqueue с нитками • 100% изоляция данных и ошибок в объектах • Работающий горячий апдейт кода • Простой как валенок и работающий штатный RPC
    52. 52. Вопросы? Макс Лапшин max@maxidoors.ru http://levgem.livejournal.com/
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×