Posterous theme by Cory Watilo

Filed under: anyevent

DBD::mysql и асинхронные запросы

Оказывается, в августе в DBD::mysql была добавлена поддержка асинхронной работы в prepare. За что спасибо Робу Хоельцу (Rob Hoelz). Теперь с версии 4.019 можно пользоваться этой фичей.

Пример асинхронной работы с mysql в Perl, используя DBD::mysql и AnyEvent http://hoelz.ro/blog/asynchronous-mysql-queries-in-perl-using-dbdmysql-and-anyevent.

В комментах я увидел, что Рокко Капутто, некогда мной любимый, жив и предлагает свои варианты на POE и Reflex. POE, привет! :-)

Это прекрасно, интересно теперь проверить стабильность работы данного решения.

 

use Perl or die;

 

Perl. AnyEvent::HTTP. Кипалив?

Я был так рад, когда перешел с POE на AnyEvent. Сразу же записал POE в ряды зла (напомню, CGI.pm – зло?!, Модули, использующие LWP::UserAgent – зло?!). Но сегодня я узнал, что AnyEvent::HTTP не поддерживает keep-alive соединения, в коде есть пара обидных комментариев:

# changing these is evilour $MAX_PERSISTENT_PER_HOST = 0;

...

         # limit the number of persistent connections         # keepalive not yet supported         if ($KA_COUNT{$_[1]} < $MAX_PERSISTENT_PER_HOST) {
              $KA_COUNT{$_[1]};
            $state{handle}{ka_count_guard} = AnyEvent::Util::guard {
               --$KA_COUNT{$_[1]}
            };
            $hdr{connection} = "keep-alive";
         } else {
            delete $hdr{connection};
         }  ...

На самом деле, AnyEvent::Handle поддерживает keep-alive, но кому-то было лень это реализовать, а меня теперь банят за большое количество соединений :)
Теперь придется все переписать на POE::Component::Client::HTTP (я, конечно, POE любил, но все-таки POE – зло! :)


ЗЫ: Скоро я расскажу про новое зло :)

ЗЫ2: Только что узнал, что Mojo::Client поддерживает keep-alive соединения, т. к. поддерживает полностью протокол HTTP 1.1.  К черту POE, "Viva la revolution!" :)

ЗЫЗЫЗЫ: Я буду писать в IronMan чаще, держись Say Perl, мои переводы будут нечто))



use Perl or die;

JFDI

Original post http://sharifulin.livejournal.com/55600.html

AnyEvent, AnyEvent::HTTP и Mojo::ByteStream

Удивление, удивление-два и привычка :)

Был удивлен, но оказывается AnyEvent/EV не позволяет выполнять вложенные condvar, получается рекурсия.
Вложенные кондвары не нужны, код легко модифицировать на работу либо с одним (самое главное send вызвать в самый последний момент, чтобы вся асинхронная работа была выполнена), либо с несколькими, тогда вызовы должны быть последовательными. Пример.

Так же был удивлён, что AnyEvent::HTTP автоматически заполняет заголовок Referer у запроса (для работы по умолчанию это лишнее) и не искейпит символы в урле (очень плохо, LWP::UserAgent и/или PoCo::Client::HTTP это делают на автомате, т.к. используют HTTP::Request).

За последнее время я так привык работать с Mojo (напомню, Mojo – pure perl http-фреймворк, "почти" без зависимостей, "веб в коробке"), что при возникновение задач вне окружения Mojo, которые связаны с перекодированием символом, не задумываясь, использую модуль Mojo::ByteStream. Например, для искейпинга символов в урле (проблема с AnyEvent::HTTP) использую следующий код:

Mojo::ByteStream->new($str)->url_escape

Для перевода html-последовательности символов вида &#1043; в печатные символы использую следующий код:

Mojo::ByteStream->new($str)->encode('utf8')->html_unescape

Очень удобно и не надо вспоминать, в каком модуле реализован данный функционал.


use Perl or die;

JFDI

Original post http://sharifulin.livejournal.com/51271.html

Запуск проектов на AnyEvent и Mojo


AnyEvent

Запустили твиттеры всех пользователей СТАНЦИИ 2.0, о котором я писал в предыдущем посте.
Используем AnyEvent::Twitter::Stream. Сам API находится в альфа-тестировании, поэтому мы работаем так же :)

Получилось очень круто, иногда интересней, чем ЧАТЕГ :)
Пишите в твиттер и слушайте СТАНЦИЮ 2.0!

Mojo

На днях запустили Рыков.ру, это первый публичный проект, полностью написанный на Mojolicious, в качестве шаблонизатора простой php-like шаблонизатор Mojo::Template, в качестве интерфейса – daemon_prefork, в момент разработки –  daemon c установленной переменной окружения MOJO_RELOAD  (изменения применяются без перезапуска), профилирование – с помошью Devel::NYProf и CGI.

В тестовом режиме запустили API для Маруси. Серверная часть написана на Mojolicious::Lite + MojoX::Renderer::JSON.
Получилось очень круто и все в одном файле, всего 246 строк :)


Что можно сказать про Mojo. Нет стабильной версии, постоянно выходят новые версии без обратной совместимости, но это нормально :)
Многие фичи приходится дописывать самому, автор лоялен к обсуждению функционала Mojo, принимает патчи, фиксит баги.
Иногда меня и мои просьбы не понимает )))
В целом, мне Mojo/Mojolicious нравится, простой и очень удобный. Даже шаблонизатор мне понравился, хотя в начале я не понимал его.

use Perl or die;

JFDI


Original post http://sharifulin.livejournal.com/50728.html

Риалтайм твиттер – риал? тайм!

У отличного сервиса Twitter есть хороший API, особенность – Streaming API, возможность получать данные из твиттера мгновенно, почти в реальном времени (риалтайм веб?).

Меня заинтересовала такая возможность, тем более есть необходимость получать статусы из твиттера всех пользователей СТАНЦИИ 2.0 (конечно, у кого есть твиттер) и отображать их на странице в реальном времени. Похожая идея реализована тут, только это видимость реального времени, т.к. делается один запрос на сервер, и постепенно по одному статусу показывается на странице, затем следующий запрос и так далее :)

На CPAN я нашел реализацию Twitter Streaming API – AnyEvent::Twitter::Stream.
С помощью модуля, действительно, очень просто получать статусы пользователей в реально времени, примера из синопсиса достаточно, чтобы быстро реализовать это.

Далее полученные статусы пользователей каким-то образом надо выводить, отдавать клиенту.
Идеальный вариант – Push-сервер и соответствующий клиент на JavaScript. Но я пока так не умею, камень преткновения – клиентская сторона (делал такое – сервер и клиент на Perl).
Я выбрал следующую реализацию (выбирал так, чтобы быстро реализовать):

  • простой и быстрый сервер – точно должен быть мультиплексирующий, думал о AnyEvent::Mojo (устарел, т.к. последний Mojo обратно не совместим, но подправить не сложно, просто не решился :), выбрал AnyEvent::HTTPD (заработал сразу :),
  • постоянно опрашивающий "тупой" клиент (jQuery решает), который выводит только новые для него сообщения,
  • формат данных – JSON (последнее время всегда такой формат выбираю, спасибо JSON::XS, очень быстро работает).
Вот такой код сервера получился.

Риалтайм твиттер заработал.
Но:

  • данный скрипт вылетает при возникновение ошибки соединения с твиттером,
  • ограничение в 150 запросов в час на API твиттера, иначе 401/406 ошибка.
Последнее "но" придется обходить: либо умышленно делать <= 150 запросов, либо отказаться от Stream API и использовать обычное API, которое по крону будет получать новые статусы пользователей.

Все-таки риалтайм веб еще далеко, но ближе, чем был год назад :)

use Perl or die;

Just F*cking Do It

Original post http://sharifulin.livejournal.com/50658.html

Perl. Коротко об AnyEvent

 AnyEvent – очень крут! :)

Ссылки по теме:

Original post http://sharifulin.livejournal.com/49693.html

Perl. Мультиплекс и AnyEvent::HTTPD

Две недели назад нужно было написать простой (легкий) веб-сервер, решил еще раз сделать выбор между POE, IO::Lambda и AnyEvent.
IO::Lambda -- сразу не заработала, позже выяснилось, что я соединение не закрывал (спасибо автору модуля за техподдержку :)
AnyEvent. Тут я взял AnyEvent::HTTPD (не от Леманна) и поразился, что модуль написан плохо, в реврайт правилах все слеши заменены на _ (ужас :), работа с тсп по нескольким модулям размазана и работает только под 5.10 (причем использованы только именнованные значения в регекспах, даже say и given нет :). За 10 минут я полностью переписал на 5.8. Заработало, но как-то не очень.
В итоге я написал на POE, решение получилось красивым, хоть по скорости пое проигрывает (немного), но достойной замены  я еще не нашел.

Вернусь к AnyEvent:HTTPD, сегодня вышел апдейт модуля и в ченже вот, что написано:

 
0.04 Sun Dec 28 15:48:28 CET 2008        - removed TCP* classes and using AnyEvent::Handle instead.        - added size and maxlength args to the C<entry> function in Appgets        - changed the API to actually call the events for all path segments          of an URL. also removed the ugly '/' => '_' mapping for the path          seperators. Sorry for any breakage in your code ;-/        - removed Perl 5.10 dependency.

ААА, он сам понял все или я управляю людьми на расстояние  :-)
 

Original post http://sharifulin.livejournal.com/41330.html

Perl. IO::Lambda

IO::Lambda версии 0.41 -- нет слов, просто супер: асинхронный DBI, очередь задач, форки и треды, самое интересное в eg/*.
[info]mcfist, очень круто, респект тебе :)


Бенчмарк tcp:

Lambda using select
0.688 sec

real        0m0.736s
user        0m0.696s
sys        0m0.036s
Lambda using AnyEvent
0.685 sec

real        0m0.737s
user        0m0.676s
sys        0m0.060s
Raw sockets using select
0.145 sec

real        0m0.181s
user        0m0.144s
sys        0m0.036s
POE using select
5.748 sec

real        0m5.863s
user        0m4.988s
sys        0m0.440s

DBI:

sub usage
{
        print <
Test implementation of non-blocking DBI. This script can work in several modes,
run with one of the parameters to switch:

   $0 thread      - use DBI calls in a separate thread
   $0 fork        - use DBI calls in a separate process
   $0 remote HOST - connect to host to port $port and request DBI there
   $0 listen      - listen on port $port, execute incoming connections
        
USAGE
        exit;
}

Скажу честно, на YAPC::Russia 2008 "May Perl"; я узнал про IO::Lambda, но тогда лямбда не впечатлила меня.
Затем пошла цепная реакция -- я услышал, что Алекс Капранов ([info]quappa) использует IO::Lambda для отправки почты, и решил более внимательно посмотреть на лямбду. Как раз подвернулась подходящая задача -- сбор данных с алексы. Я сравнил POE, AnyEvent и IO::Lambda по удобству и красоте написания, написал 3 варианта. Мне понравился AnyEvent (тогда я нашел маленький баг в дистрибутиве). Хотя на чистом аниевенте невозможно расписать некоторые задачи (спасибо за наводку Павлу Кудинову [info]pavel_kudinov), как я сейчас понимаю AnyEvent + Coro это может решить (см. презентацию Евгения Торопова с South Perl). И вот сегодня я обнаружил новую мощную версию IO::Lambda, опубликованную в мой день рождения -- 17 ноября. Теперь я не только на IO::Lambda буду смотреть, но и использовать (и рекламировать :).

Что нужно еще IO::Lambda для полного счастья? Доступ к BDB или Memcached или асинхронный клиент MySQL ? :)


Original post http://sharifulin.livejournal.com/39174.html

Perl. AnyEvent 4.21

AnyEvent обновился до 4.21, я поучаствовал в одном багфиксе :)
список изменений

4.21 Thu Jul 17 14:40:05 CEST 2008        - INCOMPATIBLE CHANGE: AnyEvent::Util::fork_call now has a prototype          which is incompatible to previous invocation syntax.        - work around more windows perl bugs in fork_call. I cannot imagine          why anybody would bother implementing fork in such an obviously          unusable way.        - avoid calling $do_retry if the request has already finished in          AnyEvent::DNS, thus avoiding an exception (reported by Anatoly          K. Sharifulin).

Original post http://sharifulin.livejournal.com/32697.html

Perl. Событийная машина и BDB

Только сегодня подумал, что POE не хватает клиента для работы с BerkleyDB или BDB.
И сегодня в новинках CPAN нахожу, что появился модуль AnyEvent::BDB - вот это то, что надо :)
Все больше начинаю смотреть в сторону AnyEvent, я до сих пор под впечатлением от бенчмарка.
Original post http://sharifulin.livejournal.com/25178.html