Обработка больших массивов данных с помощью AJAX не дает никаких преимуществ в скорости - PullRequest
2 голосов
/ 06 сентября 2011

У меня есть несколько длительных запросов к базе данных для выполнения.Каждый был построен для запуска из опции, выбранной на веб-странице.Я думал, что был довольно хитрым, запуская работу через несколько запросов AJAX .

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

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

Хуже того, AJAX-запросы на обновление страницы также ожидают в очереди, что означает, что они не отвечают до тех пор, пока все предыдущие запросы не будут выполнены.

У меня прочитано , что это может быть вызвано блокировкой сеансов PHP.

Каков обычный подход для такого рода проблем?

  • Есть ли способ заставить AJAX-запросы работать асинхронно?
  • Могу ли я остановить PHP от блокировки сеансов?
  • Должен ли я использовать отдельный процесс через cron для запуска фоновых обработок?

Спасибо!

NB. Этот проект был построен с использованием фреймворка Symfony.

AJAX использует jQuery

// Get the content
$.get('/ajax/itemInformation/slug/'+slug, function(data) {
  $('#modal-more-information').html(data);
});

1 Ответ

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

Если вы используете сеансы на всех во время любого из заданных запросов AJAX, они будут эффективно выполняться последовательно, в порядке запроса.Это связано с блокировкой файла данных сеанса на уровне операционной системы.Ключом к тому, чтобы эти запросы были асинхронными, является закрытие (или никогда не запуск) сеанса как можно быстрее.

Вы можете использовать session_write_close ( docs ), чтобы закрыть сеанс каккак можно скорее.Для этого я хотел бы использовать несколько вспомогательных функций. Приведенная ниже функция set_session_var откроет сессию, запишет переменную, а затем закроет сессию как можно быстрее и быстрее.Когда страница загружается, вы можете вызвать session_start, чтобы заполнить переменную $_SESSION, а затем немедленно вызвать session_write_close.С этого момента для записи используйте только приведенную ниже функцию set.

Функция get совершенно необязательна, поскольку вы можете просто ссылаться на глобальный $_SESSION, но мне нравится использовать это, потому что она обеспечиваетзначение по умолчанию, и я могу иметь на одну тройку меньше в основной части кода.

function get_session_var($key=false, $default=null) {
    if ($key == false || strlen($key) < 0)
        return false;
    if (isset($_SESSION[$key]))
        $ret = $_SESSION[$key];
    else
        $ret = $default;
    return $ret;
}
function set_session_var($key=false, $value=null) {
    if ($key == false || strlen($key) < 0)
        return false;
    session_start();
    if ($value === null)
        unset($_SESSION[$key]);
    else
        $_SESSION[$key] = $value;
    session_write_close();
}

Имейте в виду, что после того, как запросы AJAX станут действительно асинхронными, есть целый ряд новых соображений.Теперь вам нужно следить за условиями гонки (вам нужно с осторожностью относиться к одному запросу, задавая переменную, которая может повлиять на другой запрос) - поскольку вы видите, что при закрытых сеансах один запрос изменяется на $_SESSIONне будет виден другому запросу, пока он не перестроит значения.Вы можете избежать этого, «перестроив» переменную $_SESSION непосредственно перед критическим использованием:

function rebuild_session() {
    session_start();
    session_write_close();
}

... но это все еще подвержено состоянию гонки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...