Gen server

428 views

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
428
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
4
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Gen server

  1. 1. gen_server сервер внутри сервера Юра Жлоба для Belarus Erlang User Group
  2. 2. Все изучали, все знают, все используют. Понимание требует некоторых усилий. Чтобы понять, лучше всего написать gen_server самому :)
  3. 3. Описан во-всех книгах по Erlang Джо Армстронг “Programming Erlang”, 16-я глава Фред Хеберт “LYSE”, глава “What is OTP?”
  4. 4. Базовый паттерн OTP supervisor, gen_event, gen_fsm реализованы аналогично, но узко специализированны.
  5. 5. Приложение stdlib /usr/local/lib/erlang/lib/stdlib-1.19.4
  6. 6. gen_server http://www.erlang.org/doc/man/gen_server.html proc_lib http://www.erlang.org/doc/man/proc_lib.html sys http://www.erlang.org/doc/man/sys.html gen не документирован
  7. 7. gen_server:start_link(...)
  8. 8. gen_server:call(...)
  9. 9. gen_server:cast(...)
  10. 10. gen_server API start_link/3, start_link/4, start/3, start/4
  11. 11. Callback функции init блокирует родительский процесс timeout = infinity должна быть легковесной не должна крашиться :)
  12. 12. Callback функции init отложенная инициализация, вариант 1 init(Args) -> State = ... self() ! heavy_init, {ok, State}. handle_info(heavy_init, State) -> NewState = ... {noreply, NewState};
  13. 13. Callback функции init отложенная инициализация, вариант 2 init(Args) -> State = ... {ok, State, 0}. handle_info(timeout, State) -> NewState = ... {noreply, NewState};
  14. 14. Callback функции handle_call 8 вариантов ответа
  15. 15. Callback функции {reply, Reply, NewState} {reply, Reply, NewState, Timeout} {reply, Reply, NewState, hibernate} {noreply, NewState} {noreply, NewState, Timeout} {noreply, NewState, hibernate} {stop, Reason, Reply, NewState} {stop, Reason, NewState}
  16. 16. Callback функции handle_call(...) -> gen_server:reply(From, Reply), … {noreply, NewState}
  17. 17. Callback функции handle_cast, handle_info 4 варианта ответа
  18. 18. Callback функции {noreply, NewState} {noreply, NewState, Timeout} {noreply, NewState, hibernate} {stop, Reason, NewState}
  19. 19. Callback функции format_status формирует crash report
  20. 20. Callback функции [{data, [{"State", State}]}], [{data, [{"State", get_important_part_of(State)}]},
  21. 21. Timeout & hibernate init handle_call handle_cast handle_info
  22. 22. Timeout & hibernate init(Args) -> State = ..., {ok, State, 5 * 60 * 1000}. handle_info(timeout, State) -> io:format("~p no messages", [?MODULE]), {noreply, State, hibernate}.
  23. 23. Timeout & hibernate Hibernate Процесс занимает минимум памяти: - отбрасывается стек - проводится сборка мусора - дефрагметируется куча
  24. 24. Timeout & hibernate Hibernate Процесс редко получает сообщения, большую часть времени проводит в ожидании.
  25. 25. Отладка с помощью sys > sys:trace(e_prof, true). ok > e_prof:add_action("some", 5). *DBG* e_prof got cast {add_action,"some",5} *DBG* e_prof new state {state,[{action_accum,[115,111,109,101],[5]}], [{action_stat_set,{16,15,4},[]},{action_stat_set,{16,14,4},[]}, {action_stat_set,{16,13,4},[]},{action_stat_set,{16,12,4},[]}, {action_stat_set,{16,11,4},[]}]} ok > e_prof:add_action("some", 15). *DBG* e_prof got cast {add_action,"some",15} *DBG* e_prof new state {state,[{action_accum,[115,111,109,101], [15,5]}],[{action_stat_set,{16,15,4},[]},{action_stat_set,{16,14,4}, []},{action_stat_set,{16,13,4},[]},{action_stat_set,{16,12,4},[]}, {action_stat_set,{16,11,4},[]}]} ok > sys:trace(e_prof, false). ok sys:trace(Name, Flag)
  26. 26. Отладка с помощью sys > sys:statistics(e_prof, true). ok > sys:statistics(e_prof, get). {ok,[{start_time,{{2014,6,18},{16,14,43}}}, {current_time,{{2014,6,18},{16,17,10}}}, {reductions,360}, {messages_in,5}, {messages_out,0}]} > sys:statistics(e_prof, false). ok sys:statistics(Name, Flag)
  27. 27. Отладка с помощью sys > sys:get_state(e_prof). {state,[], [{action_stat_set,{16,21,4},[]}, {action_stat_set,{16,20,4},[]}, {action_stat_set,{16,19,4},[]}, {action_stat_set,{16,18,4},[]}, {action_stat_set,{16,17,4},[]}]} sys:get_state(Name) -> State
  28. 28. Отладка с помощью sys > sys:get_status(e_prof). {status,<0.136.0>, {module,gen_server}, [[{'$ancestors',[e_prof_sup,<0.134.0>]}, {'$initial_call',{e_prof,init,1}}], running,<0.135.0>, [{statistics,{{{2014,6,18},{16,14,43}}, {reductions,3590}, 4,0}}], [{header,"Status for generic server e_prof"}, {data,[{"Status",running}, {"Parent",<0.135.0>}, {"Logged events",[]}]}, {data,[{"State", {state,[], [{action_stat_set,{16,16,4}, [{action_stat,"some",10.0,15,...}]}, {action_stat_set,{16,15,4},[]}, {action_stat_set,{16,14,4},[]}, {action_stat_set,{16,13,4},[]}, {action_stat_set,{16,12,...},[]}]}}]}]]} sys:get_status(Name) -> Status
  29. 29. Оптимизация производительности Всем нам хочется узнать, где и как можно похачить gen_server, чтобы работало быстрее :)
  30. 30. Оптимизация производительности Луик Хоген (Loïc Hoguin) основатель компании 99s и автор Cowboy доклад на Erlang Factory 2013 Beyond OTP
  31. 31. Оптимизация производительности Так что можно сделать с gen_server?
  32. 32. Оптимизация производительности Так что можно сделать с gen_server? - убрать поддержку удаленных узлов
  33. 33. Оптимизация производительности Так что можно сделать с gen_server? - убрать поддержку удаленных узлов - убрать proc_lib:sync_wait и {ack, Pid, Result}
  34. 34. Оптимизация производительности Так что можно сделать с gen_server? - убрать поддержку удаленных узлов - убрать proc_lib:sync_wait и {ack, Pid, Result} - убрать обработку исключений try...catch
  35. 35. Оптимизация производительности Так что можно сделать с gen_server? - убрать поддержку удаленных узлов - убрать proc_lib:sync_wait и {ack, Pid, Result} - убрать обработку исключений try...catch - убрать monitor/demonitor
  36. 36. Оптимизация производительности Так что можно сделать с gen_server? - убрать поддержку удаленных узлов - убрать proc_lib:sync_wait и {ack, Pid, Result} - убрать обработку исключений try...catch - убрать monitor/demonitor - не поддерживать Timeout и hibernate
  37. 37. Оптимизация производительности Можно на 10-20% увеличить производительность, пожертвовав надежностью.
  38. 38. Оптимизация производительности Стоит оно того? Если да, то читайте про special processes в документации, смотрите примеры и делайте
  39. 39. Special processes На них построена инфраструктура OPT gen_server, gen_*, supervisor – это все они cоздаются через proc_lib:start_link
  40. 40. Special processes Хранят инфу о родительских процессах поддерживают отладку через sys отвечают на системные сообщения
  41. 41. Рекомендации по gen_server init должен быть простым и быстрым тяжелую инициализацию делаем отложено не крашимся :)
  42. 42. Рекомендации по gen_server “catch all” для всех handle_call, handle_cast, handle_info пишем в лог вместо того, чтобы крашится и терять состояние
  43. 43. Рекомендации по gen_server избегаем timeout = infinity это затрудняет диагностику dead lock
  44. 44. Рекомендации по gen_server используем call только когда действительно нужен ответ cast быстрее и не блокирует клиентский процесс
  45. 45. Рекомендации по gen_server my_server ! Msg handle_info(Msg, State) плохой стиль
  46. 46. Рекомендации по gen_server init – конструктор terminate – деструктор освобождайте ресурсы дайте terminate достаточно времени
  47. 47. Рекомендации по gen_server -spec для handle_* громоздкий и не нужный не помогает ни как документация ни как опора для dialyzer
  48. 48. Рекомендации по gen_server -spec для handle_* но если хотите, то у меня есть удобное решение :)
  49. 49. Вопросы?
  50. 50. Мой блог yzh44yzh.by

×