mcurl отличить поток "обрабатывается" от "сервер недоступен"

Тема в разделе "PHP", создана пользователем KillDead, 25 окт 2011.

Модераторы: latteo
  1. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    883
    Симпатии:
    540
    В общем возникла проблема- есть у меня либа multicurl с неблокирующими соединениями (те готовые соединения удаляются, на их новые приходят новые:(
    PHP:
        while (true) {
              
                
    // Создание потоков
    .. code
                
    // если их меньше чем Количество потоков- открываем и добавляем в $this->_curlMultiHandle новые
     
                
    curl_multi_select($this->_curlMultiHandle);

                while ((
    $mcRes curl_multi_exec($this->_curlMultiHandle$mcActive)) == CURLM_CALL_MULTI_PERFORM) {
                    
    usleep($this->_usleepTime);
                }
     

                while (
    $threadInfo curl_multi_info_read($this->_curlMultiHandle)) {
     
                 
    //  Поток $threadInfo['handle'] успешо отработал  ;
                 // закрывает его и удаляем из $this->_curlMultiHandle
                 
    ..code
                
    }
    }
    Но этот код убивает сервер если пхп меньше 5.2 - функция curl_multi_info_read не работает. И мне надо сделать аналогичный код без использования этой бажной функции. Пока решений не вижу. Сделал первое что взбрело в голову-
    PHP:
    $mh curl_multi_init();

    foreach (
    $urls as $i => $url) {

        
    $conn[$i] = curl_init($url);
      
      
    curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER1);
        
    curl_setopt($conn[$i], CURLOPT_TIMEOUT3);
        
    curl_multi_add_handle($mh$conn[$i]);

    }

    do {

        
    $ready curl_multi_select($mh);
        
    $status curl_multi_exec($mh$active);

        
    $info curl_multi_info_read($mh);

        foreach (
    $urls as $i => $url) {

            
    $h curl_getinfo($conn[$i]);

            if (!
    $h['http_code']) {
                continue;
            }
            echo 
    "САЙТ загрузился - {$h['url']} \n";
        }

        
    usleep(1000);
    } while (
    $status === CURLM_CALL_MULTI_PERFORM || $active);
    те просто в ходе работы запрашиваем информацию о всех потоках, если код ответа не 0, то удаляем поток- он готов. НО! если урл ещё обрабатывается я получаю такой ответ от curl_getinfo
    HTML:
     Array
    (
        [url] => http://www.bbc.co.uk/
        [http_code] => 0
        [header_size] => 0
        [request_size] => 0
        [filetime] => -1
        [ssl_verify_result] => 0
        [redirect_count] => 0
        [total_time] => 0
        [namelookup_time] => 0
        [connect_time] => 0
        [pretransfer_time] => 0
        [size_upload] => 0
        [size_download] => 0
        [speed_download] => 0
        [speed_upload] => 0
        [download_content_length] => 0
        [upload_content_length] => 0
        [starttransfer_time] => 0
        [redirect_time] => 0
    )
    а если сервер недоступен, я получаю аналогичный массив
    HTML:
    Array
    (
        [url] => http://www.cnnqqqqqqqqqqq.com/
        [http_code] => 0
        [header_size] => 0
        [request_size] => 0
        [filetime] => -1
        [ssl_verify_result] => 0
        [redirect_count] => 0
        [total_time] => 0
        [namelookup_time] => 0
        [connect_time] => 0
        [pretransfer_time] => 0
        [size_upload] => 0
        [size_download] => 0
        [speed_download] => 0
        [speed_upload] => 0
        [download_content_length] => 0
        [upload_content_length] => 0
        [starttransfer_time] => 0
        [redirect_time] => 0
    )
    
    Те получается блокировка- пока не пройдёт пачка положенных в мультикурл соединений- я не могу точно сказать какой поток "обрабатывается" а какой "сервер недоступен".
    Как быть? Кто может посвятить на этот вопрос?
     
  2. ZCFD

    ZCFD

    Регистр.:
    16 янв 2008
    Сообщения:
    989
    Симпатии:
    437
    не очень понял вопрос

    второй ответ - после прогона или в процессе опроса? ( если сервер недоступен, то время опроса значительно увеличивается )

    а не проще пингануть или другим образом проверить хотя бы доступность хоста, и только потом засовывать адрес в мультикурл?
     
  3. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    883
    Симпатии:
    540
    спб что откликнулся :az:

    пингануть - не вариант. Я делаю (вернее дописываю) либу, чтобы работала и с не очень старыми версиями. А что же это получается- на каждый запрос мы делаем 2, особенно если работаем через прокси- это расточительно.

    смотри, у меня идея такова-
    1) есть мультикул, в него загружается 20 (путь это макс количество) курл объектов,
    2) они обрабатываются,
    3) как только хотябы 1 получил ответ, мы его закрываем. У нас теперь обрабатывается 19.
    4) Тк 19<20 мы добавляем в мультикурл ещё 1 объект. тем самым мы не ждём пока отработает 20 потоков а постоянно держим 20 рабочих потоков

    С curl_multi_info_read всё просто - она возвращает тот поток, который Отработал . Но без этой функции - как быть?

    Опроса- это где посмотреть? После работы 2 скрипта - я получил массив для недоступного сервера cnnqqqqqqqqqqq.com
     
  4. ZCFD

    ZCFD

    Регистр.:
    16 янв 2008
    Сообщения:
    989
    Симпатии:
    437
    даже не знаю чем помочь

    ты правда на столько спешишь, что это важно доработать? мне еще ниразу не встречались объемы данных, где это было бы востребованно
     
  5. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    883
    Симпатии:
    540
    ну, я часто пытаюсь сделать всеобъятный скрипт, пренебрегая вещами которые часто могут встретится, но зато будут те, которые практически никогда не произойдут)
    Но всё таки , я считаю что 2 коннекта- это черезчур. Особенно прокси- которые дохнут прямо на ходу. Простейший пример- это чекер проксей (на курле наверно это изврат) или накрутчик. А ставить ограничения пхп для скрипта- это можно если скрипт большой. Если для небольшого сайта надо спарсить инфу в 2-4 потока, то кидать им "моя мего либа не поддерживает ваш древний серв" и заставлять их переставлять пхп - не хорошо)

    Но проблему решил. Оказалось всё просто)
    Вначале я пытался получить какую нибуть информацию с curl_getinfo - не получилось. КаллбекФункции хеадера\прогресса\обработки результата- не получали ничего. Ловил ошибки с помощью curl_errno($curl) - он возвращал что ошибочный курл нормально отработал . Но CURLOPT_STDERR писал ошибку курла в файл, уже хотел создать сокет и прослушивать на предмет ошибки , но обошлось - curl_error() - он нормально сообщает об ошибке если она произошла - Could not resolve host: cnnqqqqqqqqqqq.com; Host not found
     
  6. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    883
    Симпатии:
    540
    я рано обрадовался, оказывается как только получен заголовок, массив от curl_getinfo
    HTML:
    Array
    (
        [url] => http://ereg/proekt/pi_multicurl/test/chek.php?x=size
        [content_type] => text/html
        [http_code] => 200
        [header_size] => 175
        [request_size] => 138
        [filetime] => -1
        [ssl_verify_result] => 0
        [redirect_count] => 0
        [total_time] => 0.499
        [namelookup_time] => 0
        [connect_time] => 0.016
        [pretransfer_time] => 0.016
        [size_upload] => 0
        [size_download] => 2096959
        [speed_download] => 4202322
        [speed_upload] => 0
        [download_content_length] => -1
        [upload_content_length] => -1
        [starttransfer_time] => 0.016
        [redirect_time] => 0
        [request_header] => GET /proekt/pi_multicurl/test/chek.php?x=size HTTP/1.1
    User-Agent: Opera/7.50 (Windows ME; U) [en]
    Host: ereg 
    Accept: */*
    )
    
    выдаётся даже если курл не завершил работу. Т.е. теперь проблема другая возникла- как опредлелить- завершил работу объект или нет? Есть варинты?