Синхронизация PHP - PullRequest
       106

Синхронизация PHP

2 голосов
/ 13 сентября 2011

Я не уверен в лучшем решении для этого, но это то, что я сделал.

Я использую PHP для просмотра каталога, содержащего zip-файлы.

Эти zip-файлы содержат текстовые файлы, которые должны быть загружены в базу данных oracle через SqlLoader (sqlldr).

Я хочу иметь возможность запускать более одного процесса PHP через командную строку длязагрузите эти zip-файлы в базу данных.

Если запущены другие процессы 'php loader', они не должны перекрываться и пытаться загрузить тот же zip-файл.Я знаю, что мог бы запустить один процесс и позволить ему обрабатывать каждый zip-файл, но я бы предпочел запустить новый процесс для входящих zip-файлов, чтобы я мог загружать их одновременно.

Сейчас я создал класс, которыйзаблокирует zip-файл, каталог или общий текстовый файл, создав файл с именем «filename.ext.lock».Другой процесс, который запускается, проверит, был ли файл «заблокирован» таким образом, если он есть, он пропустит этот файл и перейдет к другому файлу для обработки.

Я создал класскоторый использует каталог и создает файлы 'идентификатора процесса', так что каждый процесс PHP имеет идентификатор, который он может использовать для целей регистрации и определения того, какой процесс PHP заблокировал файл.

Я работаю на машине с Windows и не планирую делать эту машину с Ubuntu для тех из вас, кто может предложить pcntl.

Какие другие решения вы видите?Я знаю, что это не совсем синхронизировано, потому что может быть создан файл блокировки, и затем происходит переключение контекста, а затем другой процесс PHP блокирует файл, прежде чем первый сможет создать файл блокировки.

Можете ли вы дать мне несколько идей о том, как я могу сделать это решение лучше?Реализация Java?Erlang?

Также забыл упомянуть, что процесс PHP подключается к БД для получения метаданных о файлах, которые он собирается загрузить через SqlLoader.Я не думаю, что это важно, но на всякий случай.

Быстрое примечание: я знаю, что sqlldr блокирует загружаемую таблицу и что, если несколько процессов попытаются загрузить одну и ту же таблицу, она станетгорлышко бутылки.Чтобы решить эту проблему, я планирую создать каталог, который будет содержать имена файлов после таблиц, которые в данный момент загружаются.После завершения загрузки таблицы соответствующий файл будет удален, и другие процессы проверят, безопасно ли загрузить эту таблицу.

Дополнительная информация: я использую 7zip для разархивирования файлов и exec php для выполнения этих действий.команды.

Я также использую exec для вызова sqlldr.

Размер zip-файлов может быть огромным (1 ГБ), а загрузка одной таблицы может занять до 1 часа.

Ответы [ 2 ]

0 голосов
/ 14 сентября 2011

Вместо того, чтобы создавать файл .lock, вы можете просто переименовать zip-файл, когда загрузчик начнет обрабатывать zip-файл. например «foobar.zip.bar», процесс должен быть быстрее, чем создание нового файла на диске.

Но это не гарантирует, что ваш следующий загрузчик будет загружен после переименования файла. Вы должны хотя бы немного контролирует загрузку новых загрузчиков в другом скрипте.

Кроме того, лишь некоторые побочные предложения, можно эмулировать потоки в PHP с помощью CURL, вы можете попробовать это.

https://web.archive.org/web/20091014034235/http://www.ibuildings.co.uk/blog/archives/811-Multithreading-in-PHP-with-CURL.html

0 голосов
/ 13 сентября 2011

Не знаю, правильно ли я понимаю, но у меня есть предложение: получить файлы блокировки с префиксом приоритета.

Пример: 10-script.php Запущено

20-script.php запущен (входит в цикл, ожидающий 10-foobar.ext.lock )

, а 10-foobar.ext.lock не генерируется 10-script.php , все еще ждет

30-script.php придется ждать 10-foobar.ext.lock и 20-example.ext.lock

Я попытался найти pcntl_fork с помощью cygwin, но не нашел ничего, что работает

...