За последние 24 часа нас посетили 48769 программистов и 1696 роботов. Сейчас ищут 1080 программистов ...

Помогите с идеей реализации

Тема в разделе "Прочие вопросы по PHP", создана пользователем Ensiferum, 22 ноя 2010.

  1. Ensiferum

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

    С нами с:
    11 июл 2010
    Сообщения:
    1.292
    Симпатии:
    0
    Адрес:
    из секты поклонников Нео
    Буду писать завуалированно. Есть список строк. Список большой - 500 000 и более. Есть "задания". В каждом задании участвует определенное количество строк. Задание для увеличения скорости выполняется в несколько потоков через AJAX (штук 100 потоков). Нужно, чтобы скрипт чётко знал, участвовала ли уже строка в задании, или нет.

    Сначала думал сделать так: сохраняем исходные строки в файл1, а отработанные в задании строки - в файл2. Затем через array_diff палим, какие ещё не отработали. Но при 500 000 строках скрипт завалился на бок.

    Не подскажите, как лучше сделать?
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    эээ? а бд-то? бд!
     
  3. Ensiferum

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

    С нами с:
    11 июл 2010
    Сообщения:
    1.292
    Симпатии:
    0
    Адрес:
    из секты поклонников Нео
    и как в бд?
     
  4. Gromo

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

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    лучше через БД - не будет блокировок и лишней загруженности файла
    хранить в отдельной таблице номер использованой строки (или саму строку - зависит от ситуации).
    при обращении проверять по номеру/строке была ли строка уже использована.
     
  5. Padaboo

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

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    а ассоциативный массив не катит? "string" => 0 отработала, берем несколько строк на задание, и ставим им "string" => 1
     
  6. Ensiferum

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

    С нами с:
    11 июл 2010
    Сообщения:
    1.292
    Симпатии:
    0
    Адрес:
    из секты поклонников Нео
    Padaboo
    и задавать такой массив на JS
     
  7. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    бд лучше. там можно всякие флаги навыставлять.
     
  8. Ensiferum

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

    С нами с:
    11 июл 2010
    Сообщения:
    1.292
    Симпатии:
    0
    Адрес:
    из секты поклонников Нео
    igordata
    подскажи структуру. Я чего-то не догоняю
     
  9. Gromo

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

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    Ensiferum
    приведи хоть какой-нибудь пример с данными
     
  10. Ensiferum

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

    С нами с:
    11 июл 2010
    Сообщения:
    1.292
    Симпатии:
    0
    Адрес:
    из секты поклонников Нео
    есть список ключей. их много. Они уникальные. строки в md5

    Создаётся задание: эти ключи нужно курлом отправить по одному на специально сформированный адрес. Мультикурлом не получится, так как там ещё систему авторизации проходить, потому делал так: на JS создавал огромный массив ключей, через AJAX создаю 100 запросов на обработчик, в переменных запроса указывал ID потока и часть массива (в масиве ключи помечал как "отправленные".) Как поток возвращает результат - заряжал его снова с новыми данными. Но сейчас нельзя, чтобы ключи были видны пользователю, потому надо на PHP реализовать.

    Представим, что ключи хранятся в таблице. Тогда обработчик может посылать одни и те же ключи. В этом и состоит проблема. Как именно указать обрботчику, что какие-то ключи уже посылались, а какие-то нет.
     
  11. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    PHP:
    1. <?php
    2. $arrKeys=array();
    3. $errKeys=array();
    4.  
    5. $db->select("select key from keys where send is null limit 100");
    6. while ($row=$db->fetchAssoc()){
    7.     try{
    8.         $curlSender->send($row);
    9.         $arrKeys[]=$row['key'];
    10.     }catch(Exception $e){
    11.         $loger->logException($e);
    12.         $errKeys[]=$row['key'];
    13.     }
    14. }
    15.  
    16. $keys="(".implode(',', $arrKeys).")";
    17. $errKeys="(".implode(',', $errKeys).")";
    18. $db->update("update keys set send=1 where key in $keys");
    19. $db->update("update keys set send=2 where key in $errKeys");
    Это если обработчик один.
     
  12. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    PHP:
    1. <?php
    2. $arrKeys=array();
    3. $errKeys=array();
    4.  
    5. //Этот блок может генерировать исключение, которое скорее всего надо ловить вызывающим блоком.
    6.     $db->lockTable("keys"); //Блокировку таблицы можно заменить соответствующим уровенем изолированности транзакций
    7.     $arrSelect=$db->getColumn("select key from keys where send='N' is null limit 100"); //N - Not send
    8.     $keys="(".implode(',', $arrSelect).")";
    9.     $db->update("update keys set send='W' where key in $keys"); //W - Work
    10.     $db->unLockTable("keys");
    11.  
    12. foreach($arrSelect as $key){
    13.     try{
    14.         $curlSender->send($key);
    15.         $arrKeys[]=$key;
    16.     }catch(Exception $e){
    17.         $loger->logException($e);
    18.         $errKeys[]=$key;
    19.     }
    20. }
    21.  
    22. $keys="(".implode(',', $arrKeys).")";
    23. $errKeys="(".implode(',', $errKeys).")";
    24. $db->update("update keys set send='O' where key in $keys"); // O - OK
    25. $db->update("update keys set send='E' where key in $errKeys"); // E - Error
    Теоретически это должно сработать при множестве обработчиков.
     
  13. asik

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

    С нами с:
    12 июл 2007
    Сообщения:
    211
    Симпатии:
    0
    select * from my_table where id=1 with lock
    firebird|interbase|ХЗ
     
  14. Ensiferum

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

    С нами с:
    11 июл 2010
    Сообщения:
    1.292
    Симпатии:
    0
    Адрес:
    из секты поклонников Нео
    но ещё могут быть параллельные задания.
     
  15. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    И что это меняет?
    Кстати, еще идея:
    PHP:
    1. <?php
    2.      $db->update("update keys set send='W' idSender='".$curlSender->getId()."' where send='N' limit 100");
    3.      $arrKeys=$db->getColumn("select key from keys where send='W' and idSender='".$curlSender->getId()."'");
    4.  
     
  16. Ensiferum

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

    С нами с:
    11 июл 2010
    Сообщения:
    1.292
    Симпатии:
    0
    Адрес:
    из секты поклонников Нео
    Что за классы используются?
     
  17. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Ensiferum
    Только что выдуманные. =))

    $db - класс работы с базой данных.
    $curlSender - собственно тот объект который выполняет основную работу. Что он делает - тебе виднее.
    $loger - логирует сообщения.

    Вызовы методов вполне можно заменить процедурами.
     
  18. Ensiferum

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

    С нами с:
    11 июл 2010
    Сообщения:
    1.292
    Симпатии:
    0
    Адрес:
    из секты поклонников Нео
    Спасибо за советы, буду пробовать