rolling-curl
13 мая
rolling-curl — PHP-класс для параллельного выполнения большого количества асинхронных HTTP-запросов при помощи curl, написанная Josh Fraser и поддерживаемая на данный момент мной.
Правильно чистит память, не простаивает зря, выполняя одновременно заданное число запросов. Обрабатывает каждый ответ сразу после выполнения запроса.
Пример:
// URL, которые будем обрабатывать $urls = array( "http://www.google.com", "http://www.facebook.com", "http://www.yahoo.com", ); // функция для обработки ответа function request_callback($response, $info) { // получаем title страницы if (preg_match("~<title>(.*?)</title>~i", $response, $out)) { $title = $out[1]; } echo "<b>$title</b><br />"; print_r($info); echo "<hr>"; } $rc = new RollingCurl("request_callback"); // одновременно позволим не более 20 запросов $rc->window_size = 20; foreach ($urls as $url) { // добавляем запросы в очередь $request = new Request($url); $rc->add($request); } // запускаем $rc->execute();

Комментарии
Спасибо :) Возьму на заметку :)
Как скачать?
Удобная вешь+ еще и на curl. А по асинхроным серверам на php ничего не завалялось случайно ?
Спасибо, возможно пригодится :)
Ewg
Можно забрать из SVN Google Code.
Максим
У меня лично по асинхронным нет, но есть http://github.com/kakserpom/phpdaemon.
Зачем
если можно
Вообще довольно странная библиотека...
И правда что-то не так
Почему то при запуске example.php функции curl_multi_exec и curl_multi_info_read у меня запускались по 94000 с лишним раз.
Что то там явно не так. Будто цикл какой-то крутится без таймаутов.
Там вот эта последовательность
Очень много раз повторяется (по 20-100 тыс раз)
Я бы не советовал этот класс использовать..
Да и ничуть оно ни асинхронное/неблокирующее.
Если в example.php в самом конце после $rc->execute(); вставить например print "Hello world"; то если все действительно асинхронно, то сперва напечатается "Hello world" а потом уже все остальное а тут сперва отрабатывает полностью $rc->execute(); (т.е. оно заблокировало все операции) и только потом print
Так что асинхронностью тут и не пахнет. Многопоточность разве что...
http://github.com/kakserpom/phpdaemon - ыыы, Данко! Я этого психа знаю лично - он на демонах на PHP собаку съел, целую стаю, стаж у него с этим лет 6-7 точно. Так что это реально хорошее решение будет, от опытного спеца :)
Сергей
Слово «асинхронные» тут относится именно к запросам и их обработке, а не к библиотеке в целом.
Советую почитать про curl_multi_exec и curl_multi_info_read.
Sam
Ок, насчет асинхронности в целом согласен, хотя к библиотеке в целом это не очень подходит.
Но то, что там в какой-то момент начинает крутиться цикл по 20-90 тыс итераций это явно проблема.
Сергей
Для curl_multi это совершенно нормально и указано в описаниях к методам.
Спасибо, но не пойму вот чего – я хочу сделать 5 миллионов запросов в 5 потоков. Все 5 миллионов я в $requests, понятное дело, не засуну – память не резиновая. Хотелось бы добавлять запросы в коллбэке по мере их выполнения. Однако приходится дождаться выполнения всех 5 запросов в первом потоке, и затем запускать следующий поток.
Либо делать множество более коротких очередей – скажем, 5 тысяч раз по 1000 урлов. Что уже лучше, но усложняет логику. Есть выход?
В самой библиотеке выхода, думаю, нет. Занесите в тикет, надо будет подумать.
Может ли один из урлов завесить выполнение всех запросов? Если скажем в списке урлов не яхо, а вася.пупкин.цюрюпинск.херсон.уа и на этом сервере днс сначала 3 минуты думает, а потом не отвечает и до хттп соотсветственно дело даже не доходит или доходит, но сервер выдаёт мегабайтный файл по 1 байту в секунду? :)
Нет, не может.
Возникла пара вопросов:
1) при работе скрипта (параллельно логинишься на два сайта; после этого параллельно забирается контент одной нужной страницы с каждого сайта) процес апача грузит проц на 50%. Это нормально или проблема конкретно у меня? ОС - виндовсХР, пакет - денвер+расширения, $rc->execute() - чтобы залогиниться и куки получить, второй $rc->execute()- чтобы получить контент.
2) Хотелось бы, чтобы после того как залогинишься на сайте, сразу начинал работать другой запрос для получения контента страницы, и после получения парситься, независимо от запросов к другим сайтам. Такое возможно с данным функционалом?
Привет!
Спасибо за либу. Очень пригодилось.
Есть вопрос.
С учетом того, что:
запросов допустим 1000, а
, то либа должна отрабатывать каждые 3 сек минимум 20 запросов. Независимо от скорости получения контента (ибо CURLOPT_TIMEOUT => 3). Значит на всю операцию должно уйти не более 150 сек. Добавим 150 сек для прочих операций. Итого 5 мин. Однако, на деле может и час и два работать. Такое впечатление, что после первых 20 потоков переходит в режим однопоточности + не работает CURLOPT_TIMEOUT.
С чем может быть связано?
в догонку к предыдущему посту
как-то эти цифры не совместимы с
версия curl libcurl/7.19.6
может дело в самой либе curl?
Jei
1) Не уверен. У меня не наблюдается.
2) Да, в коллбэках писать надо.
Turbonist
Скорее всего в curl. Параметры либе вроде передаются.
на кодах в вопросах, 12 вопрос, чел тоже испытывает проблемы с тем же самым.
вообще таймаут - это единственное, что пока не позволяет поменять сокеты на курл.