Вопрос про handle_info(timeout, State)

122 views
Skip to first unread message

nt

unread,
Jan 16, 2013, 2:45:37 PM1/16/13
to erlang-...@googlegroups.com
А это сообщение может приходить извне, в каких-то еще случаев, кроме последнего параметра в init/handle_call/handle_cast/handle_info?
Я так понял, этот таймаут вообще никак не связан с пятисекундным таймаутом ожидания сообщения?

JLarky

unread,
Jan 16, 2013, 2:58:21 PM1/16/13
to erlang-...@googlegroups.com
в принципе может, как и любое другое сообщение приходящее в мейлбокс :)
да, он никак не связан с с пятисекундным дефолтным таймаутом ожидания
call (или о чём вы там?) потому что такой штуки как ожидание сообщения
вообще нет. Ну то есть кроме конструкции
receive
....
after 5000 -> timeout
end
вот этот код будет "ожидать сообщение" 5 секунд.

2013/1/16 nt <nmt...@gmail.com>:

> --
> --
> Страница рассылки: http://groups.google.com/group/erlang-russian
> Новости: http://erlanger.ru
> Чат: xmpp://erl...@conference.jabber.ru
> Чат для оффтопа: xmpp://erlang...@conference.jabber.ru
> Правила, действующие в чате и рассылке:
> http://erlanger.ru/ru/erlang-at-conference-jabber-ru
>
> Написать письмо: erlang-...@googlegroups.com
> Отписаться: erlang-russia...@googlegroups.com
>
>

nt

unread,
Jan 16, 2013, 3:46:57 PM1/16/13
to erlang-...@googlegroups.com
да, я имел ввиду gen_server:call.

Просто меня смущает - часто в примерах всякие вещи типа инициализации или блокирующие штуки вроде чтения из сокета выполняются  в handle_info(timeout...), ведь по идее это очень небезопасно, разве нет? :) Вот здесь в рассылке обсуждался другой способ отложенной инициализации, через proc_lib:init_ack({ok, self()}), мне он гораздо более логичным показался.

среда, 16 января 2013 г., 23:58:21 UTC+4 пользователь JLarky написал:

Maxim Treskin

unread,
Jan 17, 2013, 11:32:58 PM1/17/13
to erlang-...@googlegroups.com

2013/1/17 nt <nmt...@gmail.com>

Просто меня смущает - часто в примерах всякие вещи типа инициализации или блокирующие штуки вроде чтения из сокета выполняются  в handle_info(timeout...), ведь по идее это очень небезопасно, разве нет?

Нет, это абсолютно безопасно, так как такое сообщение посылается самому себе сразу после старта процесса через 0 миллисекунд. Больше никто в это время про Pid процесса не знает и послать ему пока ничего не может. Но такой вид отложенной инициализации сбивает с толку и при взгляде на незнакомый код заставляет думать, из-за чего приходит сообщение timeout. Поэтому надо использовать либо proc_lib:init_ack({ok, self()}), если делается собственный процесс, не основанный на каком-либо behaviour, либо из функции init() явно посылать себе сообщение об инициализации, например, {init}.


--
Max Treskin

Valery Meleshkin

unread,
Jan 18, 2013, 2:49:17 AM1/18/13
to erlang-...@googlegroups.com
Это не _абсолютно_ безопасно с той точки зрения, что атом timeout можно через месяц зачем-то послать самому себе откуда-нибудь ещё без всякой задней мысли :)

пятница, 18 января 2013 г., 8:32:58 UTC+4 пользователь Max Treskin написал:

JLarky

unread,
Jan 18, 2013, 3:48:21 AM1/18/13
to erlang-...@googlegroups.com
ну так надо проверять значит при приходе атома timeout в каком
состоянии он пришел. То есть скажем если у нас в стейте
table=undefied, то значит мы только запустились и таблицу ещё не
создали, значит нужно написать
handle_info(timeout, #state{table=undefined}) ->
%% init

а случай, когда это сообщение придёт случайно поступать с ним так же
как с другими левыми сообщениями пришедшими в handle_info

2013/1/18 Valery Meleshkin <nekro...@gmail.com>:

Maxim Treskin

unread,
Jan 18, 2013, 3:56:06 AM1/18/13
to erlang-...@googlegroups.com
Безопасно в том смысле, что это сообщение будет абсолютно точно доставлено самым первым. Да, его может послать кто-нибудь иной, поэтому никогда не надо делать отложенную инициализацию через таймаут. Где написано обратное, там ложь.


2013/1/18 JLarky <jla...@gmail.com>



--
Max Treskin

JLarky

unread,
Jan 18, 2013, 4:20:03 AM1/18/13
to erlang-...@googlegroups.com
2013/1/18 Maxim Treskin <zert...@gmail.com>:

> Безопасно в том смысле, что это сообщение будет абсолютно точно доставлено
> самым первым. Да, его может послать кто-нибудь иной
вот до сюда я понимаю

> поэтому никогда не надо делать отложенную инициализацию через таймаут.
а почему по этому? любое сообщение тебе может послать любой процесс,
эрланг работает только в условиях, когда код на всех нодах может
выполняться только благонадёжный код. Чем хуже левое сообщение по
сравнениею например с kill?

Maxim Treskin

unread,
Jan 18, 2013, 5:00:08 AM1/18/13
to erlang-...@googlegroups.com
Согласись, что вероятность получить неожиданное сообщение timeout намного выше, чем, например, gen_server:cast(self(), {init}).


2013/1/18 JLarky <jla...@gmail.com>



--
Max Treskin

Andy

unread,
Jan 18, 2013, 9:13:48 AM1/18/13
to erlang-...@googlegroups.com
У меня так случилось :) , что вместо инициализации используется периодическое обновление кеша. Вернее, оно является и инициализацией тоже, ибо этот процесс больше ничего не делает, кроме как раздает кешированные данные. Поэтому, я зову это сообщение 'periodical'. А от повторного срабатывания в случае нужды, да, можно защититься флажком в стейте. Или терм использовать позаковыристее...

JLarky

unread,
Jan 18, 2013, 6:23:24 PM1/18/13
to erlang-...@googlegroups.com
> Согласись, что вероятность получить неожиданное сообщение timeout намного
> выше, чем, например, gen_server:cast(self(), {init}).
соглашусь только на тех условиях, что автор этого сообщения я же сам.
То есть только на тех основаниях, что я сам могу себе послать случайно
timeout ещё для одного случая вместо инициализации, а {init} случайно
для чего-то отличного от инициализации я себе сам послать скорей всего
не смогу :)
Reply all
Reply to author
Forward
0 new messages