Параллельное выполнение скриптов PHP
Здравствуйте. Делаю функцию импорта содержимого .csv файла в базу данных MySQL. Записей более 40 000 плюс надо проверять на дубликаты. Никакими усилиями не удалось запихнуть время работы в разумные 30 секунд. Решил запускать в фоне с помощью AJAX запроса. А другим AJAX-ом время от времени проверять статус выполнения.
Первый скрипт циклически переписывает файл в базу и записывает текущее значение в переменную $_SESSION['import'].
public function action_importcore() {
$auth = Auth::instance();
if ($auth->logged_in()) {
if (isset($_GET['file'])and(isset($_GET['group']))) {
$filename = $_SERVER['DOCUMENT_ROOT'].'/bases/'.$_GET['file'];
$group = ORM::factory('group', $_GET['group']);
$_SESSION['fullimport'] = filesize($filename);
$fp = fopen($filename, 'r');
$colum = fgetcsv($fp, 255, ';');
set_time_limit(0);
while ($dt = fgetcsv($fp, 255, ';')) {
$person = ORM::factory('person', array($colum[1] => $dt[1]));
if ($person->loaded()) {
if (!$person->has('group', $group->id))
$person->add('group', $group);
} else {
$person->set($colum[1], $dt[1])->set($colum[0], $dt[0])->save();
$person->add('group', ORM::factory('group', $group));
}
$_SESSION['import'] = ftell($fp);
}
} else {
$this->request->redirect('/');
}
} else {
$this->request->redirect('/');
}
}
Второй считывает значение $_SESSION['import'], считает процент и отдает AJAX-у.
public function action_importping() {
$auth = Auth::instance();
if ($auth->logged_in()) {
if (isset($_SESSION['import'])and(isset($_SESSION['fullimport']))) {
echo round($_SESSION['import']/$_SESSION['fullimport']*100);
} else {
echo 50;
}
} else {
$this->request->redirect('/');
}
}
Проблема в том что во время выполнения первого скрипта второй не отвечает. Вообще никакой скрипт не отвечает! Веб-сервер (кстати Apache 2.2.22 под Windows) отдает картинки и статические страницы, но виснет при запросе к любому .php скрипту. Как только первый скрипт завершает работу, все остальные могут запускаться.
Помогите разобраться в чем причина?
Первый скрипт циклически переписывает файл в базу и записывает текущее значение в переменную $_SESSION['import'].
public function action_importcore() {
$auth = Auth::instance();
if ($auth->logged_in()) {
if (isset($_GET['file'])and(isset($_GET['group']))) {
$filename = $_SERVER['DOCUMENT_ROOT'].'/bases/'.$_GET['file'];
$group = ORM::factory('group', $_GET['group']);
$_SESSION['fullimport'] = filesize($filename);
$fp = fopen($filename, 'r');
$colum = fgetcsv($fp, 255, ';');
set_time_limit(0);
while ($dt = fgetcsv($fp, 255, ';')) {
$person = ORM::factory('person', array($colum[1] => $dt[1]));
if ($person->loaded()) {
if (!$person->has('group', $group->id))
$person->add('group', $group);
} else {
$person->set($colum[1], $dt[1])->set($colum[0], $dt[0])->save();
$person->add('group', ORM::factory('group', $group));
}
$_SESSION['import'] = ftell($fp);
}
} else {
$this->request->redirect('/');
}
} else {
$this->request->redirect('/');
}
}
Второй считывает значение $_SESSION['import'], считает процент и отдает AJAX-у.
public function action_importping() {
$auth = Auth::instance();
if ($auth->logged_in()) {
if (isset($_SESSION['import'])and(isset($_SESSION['fullimport']))) {
echo round($_SESSION['import']/$_SESSION['fullimport']*100);
} else {
echo 50;
}
} else {
$this->request->redirect('/');
}
}
Проблема в том что во время выполнения первого скрипта второй не отвечает. Вообще никакой скрипт не отвечает! Веб-сервер (кстати Apache 2.2.22 под Windows) отдает картинки и статические страницы, но виснет при запросе к любому .php скрипту. Как только первый скрипт завершает работу, все остальные могут запускаться.
Помогите разобраться в чем причина?
1 ответов
Так и должно быть. Скрипты использующие сессию не могут работать одновременно от общей сессии, пока сессия открыта. Таким образом обеспечивается целостность данных внутри сессии.
Используйте другое место, для обмена данными между скриптами. Шаред мемори, mysql, файлы, memcache.....