Cowboy + cowboy_loop_handler

126 views
Skip to first unread message

Дмитрий Макеев

unread,
Dec 2, 2013, 8:00:18 AM12/2/13
to erlang-...@googlegroups.com
Добрый день!

Не могу понять в ковбое вот какой вещи: когда поступает http запрос, ковбой создает поток, который занимается ответом. И как я понимаю для не loop_handler он сначала запускает init и потом один раз handle(Req, State).

Но в случае с loop_handler все сложней, он запускает init, но вот хэндла нет, есть только info({reply, Body}, Req, State), но как мне обратиться к нему "со стороны"? С поведением gen_server я делаю call если знаю либо имя либо PID, а тут мне мало того, что PID Никто не сказал, так еще и это никакой не gen_server.

И еще по поводу того же loop_handler - Как мне изменить то, что он ответит на timeout? как я понял в terminate нельзя написать cowboy_req:reply, может быть потому-то объект Req уже уничтожен (соединение там закрыто или что-то подобное), тогда как быть? В документации написано, что он ответит 204 No Content (http://ninenines.eu/docs/en/cowboy/HEAD/guide/loop_handlers/), но если мне надо 200 и нормальный ответ?

Заранее спасибо!

Max Lapshin

unread,
Dec 2, 2013, 8:02:28 AM12/2/13
to erlang-...@googlegroups.com
С cowboy_loop_handler надо в init зарегистрировать self() в каком-то источнике и в info ждать событие от этого источника, пропуская всё что не интересно.

Получив нужное событие надо ответить и выйти.

Дмитрий Макеев

unread,
Dec 2, 2013, 8:30:21 AM12/2/13
to erlang-...@googlegroups.com
Спасибо за подсказку, а источник что должен вызвать? Или просто отправка сообщения через "!" ?

понедельник, 2 декабря 2013 г., 17:02:28 UTC+4 пользователь Max Lapshin написал:

Дмитрий Макеев

unread,
Dec 2, 2013, 9:10:31 AM12/2/13
to erlang-...@googlegroups.com
Так, все, с отправкой разобрался, действительно простая отправка сообщения. Осталось разобраться с ответом по тайм-ауту

понедельник, 2 декабря 2013 г., 17:30:21 UTC+4 пользователь Дмитрий Макеев написал:

Alex Bubnoff

unread,
Dec 3, 2013, 5:45:15 AM12/3/13
to erlang-...@googlegroups.com
Просто в handler:init() делаете Ref = erlang:send_after(1000, self(), timeout), Ref сохраняете в стейте запроса. Если ответ пришел до сообщения timeout - erlang:cancel_timer(Ref). Если timeout таки пришло - отвечаем про него, завершаемся.

А вообще мне не совсем ясна конечная цель всего этого - зачем таймауты именно на loop-хэндлерах. Навскидку это выглядит эквивалентно gen_server:call с обработкой таймаута из обычного хэндлера.

понедельник, 2 декабря 2013 г., 18:10:31 UTC+4 пользователь Дмитрий Макеев написал:

Дмитрий Макеев

unread,
Dec 3, 2013, 6:00:42 AM12/3/13
to erlang-...@googlegroups.com
Ну т.е. тут отказ от loop хэндлера, и использование обычного хэндлера вместе со штатными средствами erlang? 
Но ведь разработчики Ковбоя не просто так делали поведение loop_handler? Но Ваш план мне тоже нравится, возьму на вооружение.

вторник, 3 декабря 2013 г., 14:45:15 UTC+4 пользователь Alex Bubnoff написал:

Max Lapshin

unread,
Dec 3, 2013, 6:00:56 AM12/3/13
to erlang-...@googlegroups.com
gen_server:call по таймауту вываливается с exit. 
Это логически не то, что нужно, потому что по таймауту в HTTP надо просто извиниться и послать пустой ответ 

Дмитрий Макеев

unread,
Dec 3, 2013, 8:18:15 AM12/3/13
to erlang-...@googlegroups.com
Да, согласен, но для некоторых пользователей было бы лучше получить 200 и сообщение какое-нибудь, чем обрабатывать 204. (не знаю как на самом деле, но все PHP программисты всегда просят у меня 200 код ответа, а уже подробности в теле)

вторник, 3 декабря 2013 г., 15:00:56 UTC+4 пользователь Max Lapshin написал:

Alex Bubnoff

unread,
Dec 3, 2013, 8:23:47 AM12/3/13
to erlang-...@googlegroups.com
case (catch gen_server:call(...)) и 503 с пометкой server overloaded. Но если у этого варианта есть минусы, я буду рад их услышать.

вторник, 3 декабря 2013 г., 15:00:56 UTC+4 пользователь Max Lapshin написал:
Reply all
Reply to author
Forward
0 new messages