Проверьте активные таймеры в Эрланге - PullRequest
10 голосов
/ 29 октября 2010

Есть ли простой способ получить список всех ожидающих в настоящее время таймеров, начинающихся с erlang:send_after, erlang:apply_after и т. Д. В Erlang?

Ответы [ 5 ]

6 голосов
/ 30 октября 2010

В целях отладки вы можете использовать dbg:).

Сначала создайте таблицу ets, в которой будут храниться все ссылки на таймеры.

1> ets:new(timer_dbg, ['public', 'named_table', 'bag']).
timer_dbg

Затем создайте функцию-обработчик dbg, котораяпроверяет вызовы, возвращаемые из erlang: send_after, и сохраняет возвращенную ссылку таймера в таблицу

2> Fun = fun({'trace', _Pid, 'return_from', {erlang, send_after, 3}, Ref}, []) ->
2>           ets:insert(timer_dbg, {Ref}), [];
2>          (_Msg, []) ->
2>           []
2>       end.
#Fun<erl_eval.12.113037538>

Установить функцию в качестве обработчика трассировки.Также включите сопоставление при вызове к erlang:send_after() во всех процессах

3> dbg:tracer('process', {Fun, []}).
{ok,<0.35.0>}
4> dbg:p('all', 'c').
{ok,[{matched,nonode@nohost,26}]}
5> dbg:tpl(erlang, send_after, [{'_', [], [{'return_trace'}]}]).
{ok,[{matched,nonode@nohost,1},{saved,1}]}

Сделайте несколько тестовых вызовов к erlang:send_after()

6> erlang:send_after(1000, self(), {}).
#Ref<0.0.0.43>
7> erlang:send_after(1000, self(), {}).
#Ref<0.0.0.47>
8> erlang:send_after(1000, self(), {}).
#Ref<0.0.0.51>

Наконец, убедитесь, что таблица содержит эти ссылки:

9> ets:tab2list(timer_dbg).
[{#Ref<0.0.0.51>},{#Ref<0.0.0.43>},{#Ref<0.0.0.47>}]

Таким образом, вы будете хранить все ссылки на таймеры, когда-либо созданные любым процессом, когда-либо вызывающим erlang:send_after().Вы можете сопоставить их с erlang:read_timer(), чтобы отфильтровать живые таймеры.

Вы можете отследить вызовы на send_after аналогичным образом.Также можно выполнить поиск по cancel_timer и вручную удалить отмененные ссылки из таблицы.

Кроме того, если у вас нет приложения с интенсивным обменом сообщениями, вы сможете найти соответствие по сообщениям и /или функции, запускаемые этими таймерами, и удаляют просроченные ссылки из списка.

2 голосов
/ 05 ноября 2010

Я столкнулся с той же необходимостью отслеживания таймеров сегодня.

Он находится на производстве, поэтому я не хочу использовать dbg. Это таймеры erlang: поэтому мое предыдущее решение бесполезно.

Вместо этого я проанализировал параметр nbif_timer из binary_to_list (erlang: system_info (info)).

Я полагаю (пока не подтвердил), он сообщает о памяти, выделенной для таймеров. В моей системе x64 было бы 17 слов по 8 байт = 136 байт.

Контроль этого значения ясно показывает, когда система устанавливает большое количество таймеров.

наслаждаться.

2 голосов
/ 29 октября 2010

Глядя на код в erl_bif_timer.c Я думаю, что аварийный дамп - единственное место, где вы можете найти список всех таймеров BIF, которые были только активны.: -)

1 голос
/ 29 октября 2010

это взлом, но используйте: ets: tab2list (timer_tab). Для двух таймеров это имеет место:

  ets:tab2list(timer_tab).                                            
[{{1288384968923398,#Ref<0.0.0.30>},
  timeout,
  {erlang,integer_to_list,[23]}},
 {{23334621698390115688,#Ref<0.0.0.189>},
  timeout,
  {erlang,integer_to_list,[23]}}]
0 голосов
/ 29 октября 2010

вы можете сохранить ссылки, возвращенные send_after, aply_after и т. Д., И использовать erlang: read_timer, чтобы проверить, ожидает ли он еще (read_timer возвращает false, если таймер был отменен или больше не ожидает)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...