За последние 24 часа нас посетили 17928 программистов и 1613 роботов. Сейчас ищут 1444 программиста ...

Помогите придумать алгоритм

Тема в разделе "Решения, алгоритмы", создана пользователем RomanBush, 16 мар 2008.

  1. RomanBush

    RomanBush Активный пользователь

    С нами с:
    5 дек 2007
    Сообщения:
    798
    Симпатии:
    0
    Адрес:
    200 км от Москвы
    Задача - скачать xml-ку, в которой данные. Среди данных - пути к картинкам, которые надо перекачать к себе.
    С xml-кой всё понятно, всё нормально. Сделал.
    Загвоздка в том, что картинок, которые надо перекачать - около 300 мегабайт. Соответственно, 30 секунд (max_execution_time по умолчанию) естественно - не хватает. Выставлять max_execution_time равным 6000 секунд, чтобы гарантировано, при любых тормозах и сбоях в канале, хватало времени скачать картинки - мне кажется неправильным. :)
    Помогите придумать алгоритм, как обойти ограничение max_execution_time, и при этом таки скачать картинки.
    Я так понимаю, что надо сделать какую-то аяксовую связку. Но что-то ничего толкового не приходит в голову.
     
  2. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Сделай консольный скрипт, который берёт фаил с линками и выкачивает их в нужное место.
    Тогда работа будет такой:
    Обработал XML, записал всё в txt фаил (линк на строку). В конце вызвал консольный скрипт через system('php myphpscript.php > /dev/null');
    В тоге и WEB скрипт быстро обработает всё и закончится, и в системе будет работать свой скрипт, который без проблем вытянет все картинки, т.к. он не имеет ограничение по времени исполнения
     
  3. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    RomanBush
    Возможно глупость, но делать редирект каждые 25 секунд на ту же страницу, но с другими гет-параметрами.

    Не уж то все 300 мегабайт на разных серверах храняться?
     
  4. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Kreker
    Это именно глупость с редиректом...
     
  5. RomanBush

    RomanBush Активный пользователь

    С нами с:
    5 дек 2007
    Сообщения:
    798
    Симпатии:
    0
    Адрес:
    200 км от Москвы
    На одном. Но - стороннем, с другим хозяином.
    Ну это действительно - не очень.
    У меня была мысль - через определённое кол-во файлов заканчивать работу и делать новую страницу с редиректом. Но - тоже не очень хорошее решение.
    Интересный вариант. Оставлю "про запас", на случай, если ничего больше не придумается.
    Дело в том, что сильно хотелось бы ограничится средствами php+аякс.

    Видел один сайт-анализатор. Но, к сожалению, не могу вспомнить ни адрес, ни как его нашёл.
    Там было примерно так - он парсил выдачу яндекса по запросу "все страницы введённого сайта". Лез на каждый сайт из выдачи и что-то (не помню что) там анализировал. Обрабатывал около 200-300 сайтов. Весь этот скрипт работал на одной странице. Время работы было - около часа. А выглядело это так - он проходил очередной сайт и тут же рисовал новую строку (итоговую) на экране. Сделан скрипт был на php.
    А вот алгоритм подсмотреть - не могу. Потому что не помню, что это за сайт.
    Вот хочется сделать примерно такое же.
     
  6. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    А что аякс будет делать? Те же, каждые 30 секунд посылать разные запросы на одну и ту же страницу с разным гетом.
     
  7. Clone

    Clone Guest

    А что, обязательно пхп? Другие языки уже не рулят? И, честно говоря, не понимаю, чего бояться max_execution_time?
    Я делал такое. суть: echo + flush() И никакой AJAX не нужен.
     
  8. RomanBush

    RomanBush Активный пользователь

    С нами с:
    5 дек 2007
    Сообщения:
    798
    Симпатии:
    0
    Адрес:
    200 км от Москвы
    Не понял. Скрипт-то отрубается по max_execution_time. Или есть какие-то варианты этого избежать?
     
  9. antonn

    antonn Активный пользователь

    С нами с:
    10 июн 2007
    Сообщения:
    2.996
    Симпатии:
    0
    Psih
    и совсем не глупость
     
  10. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    RomanBush
    Эм, а причём тут AJAX? Надо делать именно так, как я сказал. Такие вещи делать стредствами WEB части PHP очень плохо. Нагрузка на WEB сервер, занят PHP процесс. И не дай бог кто-то этот линк найдёт и закидает сервер запросами на него. Это для безопасности очень плохо.
    А вариант с браузером для такого долго работающего скрипта имеет кучу недостатков - нельзя закрывать браузер, это раз. Малейший notice на стороне PHP - получите ошибку что headers allready sent и редиректа не будет, и.т.д. Да и про безопасность я писал. А консольный скрипт можно хоть по cron выполнять. Удобно и секюрно. Можно вставить sleep в скрипт, что-бы он не сильно грузил сервер и.т.д. Просто пишите статус в базу/фаил и проверяйте эти статусы другим скриптом в WEB интерфейсе как идёт процесс.

    З.Ы. Я бы вообще подумал-бы о том, что бы написать этот скрипт на bash
     
  11. Clone

    Clone Guest

    set_time_limit(0);
    ignore_user_abort(true);

    Но вот про гипотетическую безопасность это да... Да и удобнее, имхо, будет на другом языке слабать, хотя кому как...
     
  12. RomanBush

    RomanBush Активный пользователь

    С нами с:
    5 дек 2007
    Сообщения:
    798
    Симпатии:
    0
    Адрес:
    200 км от Москвы
    Тоже к этому пришёл в своих рассуждениях.
    В принципе, я уже начал его писать, только не успел дописать - заснул. :)
     
  13. RomanBush

    RomanBush Активный пользователь

    С нами с:
    5 дек 2007
    Сообщения:
    798
    Симпатии:
    0
    Адрес:
    200 км от Москвы
    Интересное наблюдение. Если вызываю скрипт через system() - процесс в памяти жрёт от 9 до 9,5 метров. А если его же вызываю через exec() - жрёт от 6 до 6,5 метров.
    Почему так? И как правильнее в данном случае его вызывать? В обеих случаях при отключении юзера процесс продолжает работать. Жаба подсказывает, что надо вызывать через exec(), но мне кажется, что тут есть какая-то засада. Только не пойму какая.
     
  14. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Сорри, только заметил тему...
    Если вопрос еще актуален, вот как я обычно это делаю:
    1. Создаю временную табличку MySQL
    2. Загоняю туда все задания на обработку (адреса картинок в данном случае)
    3. Запоминаю время начала работы скрипта.
    4. Делаю цикл: пока в таблице есть хоть одна запись - выдергиваю ее, обрабатываю, удаляю. Если время работы скрипта приближается к критическому - делаю Javascript-редирект на 3. В противном случае - GOTO 4.
    5. Удаляю пустую таблицу.

    Вариант хорош тем, что даже если работа скрипта по каким-то причинам прервалась (или была прервана), состояние сохраняется в таблице. И можно просто перезапустить скрипт обработки, и он продолжит со следующего по счету задания. Можно не удалять записи, а помечать как удаленные, можно выбирать не по одной, а по 10-20... тут уж как фантазия разыграется :)
     
  15. RomanBush

    RomanBush Активный пользователь

    С нами с:
    5 дек 2007
    Сообщения:
    798
    Симпатии:
    0
    Адрес:
    200 км от Москвы
    Dagdamor
    Это уже стало понятно, когда принципиально определился с алгоритмом. Единственное, что я "тормознул" (почему-то, видимо всё-таки надо отдыхать периодически) - за каким-то хреном стал использовать вместо БД файл для хранения списка файлов на закачку. Сейчас сижу, мучаюсь, как удалять из этого файла уже скачанные картинки, при том, чтобы при обрыве скрипта файл не грохался. Ща перепишу на БД.

    PS. Блин, если начало клинить - пора на пару дней отвлечся.
     
  16. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Как же это правильно!
     
  17. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    не, это все же стоит загнать в крон или как-то похоже. Понятно что с контролем уже произведенных действий.
     
  18. RomanBush

    RomanBush Активный пользователь

    С нами с:
    5 дек 2007
    Сообщения:
    798
    Симпатии:
    0
    Адрес:
    200 км от Москвы
    Дык тут получается универсально - если есть возможность/желание - загоняешь в крон. Если нет - вызываешь прям из страницы загрузки.
    У крона есть минус - реальное обновление данных происходит раз в неделю. Но - непредсказуемо. Может и два раза за день произойти. И, при таких условиях - какую частоту запуска ставить? Раз в день - может не хватить. Раз в час - получится, что 24*7=168 - то есть 167 раз крон сработает вхолостую. Но базу хоть раз дёрнет. А нафига? А system() - обновил данные, очередь на закачку сформировал - и фик с ним, пускай качает.
    Короч - мне, по большому счёту пофик - заказчику расскажу все плюсы/минусы, а он сам пусть решает - как ему удобнее, так и будет использовать.