Проблема записи в кэш WordPress с несколькими сессиями - PullRequest
0 голосов
/ 20 апреля 2010

Я работаю над настраиваемым плагином для переносчика контента в WordPress, который мой клиент попросил меня создать. Он говорит, что хочет, чтобы он перехватывал событие просмотра страницы и, если это подходящее время суток (24 часа с момента последнего сообщения), извлекал файл ресурса и выводил другое сообщение. Ему нужно было также поднять флаг и не дать другим сеансам запустить тот же фрагмент кода. Итак, поднимите какой-нибудь флаг, говорящий: «Я публикую этот пост, уйду из другого процесса», а затем он делает этот пост и снова выпускает флаг.

Однако самое странное происходит, когда он загружен несколькими сеансами, попадающими на сайт с просмотром страниц. Он запускает вместо одного поста - он случайным образом делает 1, 2 или 3 лишних поста, при этом каждый думает, что это было подходящее время для поста, потому что прошло 24 часа после времени последнего поста. Поскольку это несколько случайно, я предполагаю, что проблема в некотором кешировании записи, когда другие сеансы еще не видят поднятый флаг, пока не пройдет пара микросекунд.

Плагин поднимал «флаг», просто записывая данные в таблицу wp_options с помощью API update_option () в WordPress. Другие сеансы пользователя должны были прочитать это значение с помощью get_option () и увидеть флаг, а затем не запускать тот фрагмент кода, который создает сообщение, потому что данный сеанс уже делал это. Затем, когда закончите, я опускаю флаг, и другие сеансы продолжаются как обычно.

Но то, что он делает, это пропускает другие сессии.

Чтобы сделать это, я использовал add_action ('loop_start', 'checkToAddContent'). Странная вещь в этой функции заключается в том, что она вызывается более одного раза на странице, и на самом деле некоторые плагины могут вызывать ее. Я не знаю, есть ли лучшее событие, чтобы зацепить. Тем не менее, даже если я найду событие для перехвата, которое запускается только один раз при просмотре страницы, у меня все равно есть несколько сеансов, с которыми приходится бороться (разные пользователи, которые могут просматривать страницу одновременно), и я хочу, чтобы только один данный сеанс вызывал содержание сообщения, когда оно должно быть в расписании.

Мне интересно, есть ли какие-нибудь разработчики плагинов WordPress, которые могли бы предложить другую зацепку для события, чтобы зацепиться за нее, и найти другой способ поднять флаг, который увидят все сессии. Я имею в виду, что я мог бы использовать API разделяемой памяти в PHP, но во многих планах хостинга это отключено. Невозможно использовать cookie или var сессии, потому что это только один сеанс. Единственное, что может работать в разных планах хостинга, - это вместо этого удалить файл как флаг. Если файл присутствует, то один сеанс имеет флаг. Если файл отсутствует, другие сеансы могут попытаться получить флаг. Конечно, я мог бы использовать файловый маршрут, но, на мой взгляд, он немного незрелый, и мне было интересно, смогу ли я что-нибудь сделать в WordPress.

Ответы [ 2 ]

1 голос
/ 21 апреля 2010

Ключ может заключаться в создании записи семафора в базе данных для события "drip".

Предупреждение - рассмотрите следующий псевдокод - я не ищу функции.

Когда сообщение запрашивается, используйте оператор SQL, например

$ts = get_time_now(); // or whatever the function is
$sid = session_id();

INSERT INTO table (postcategory, timestamp, sessionid)
VALUES ("$category", $ts, "$sid")
WHERE NOT EXISTS (SELECT 1 FROM table WHERE postcategory = "$category"
    AND timestamp < $ts - 24 hours)

Целостность базы данных сделает это атомарным, поэтому можно вставить только одну запись. и вставка будет иметь место только в случае превышения временного интервала.

Затем немедленно проверьте, являются ли текущие session_id () и отметка времени вашими. Если они есть, капайте.

ВЫБРАТЬ сессионный идентификатор из таблицы ГДЕ postcategory = "$ postcategory" И отметка времени = $ ts AND sessionid = "$ sid"

0 голосов
/ 21 апреля 2010

Такая проблема возникает при запросах страниц даже из одного сеанса (того же посетителя), но также может возникать при запросах страниц от отдельных посетителей. Это работает так:

  • Если вы делаете утечку контента, то запрос страницы, вероятно, является тем, что вы перехватываете с помощью add_action ('wp', 'myPageRequest'). Оттуда, если запланированное сообщение является обязательным, вы создаете новое сообщение.

  • Пост занимает немного времени для записи в базу данных. В это время запрос get_posts () может еще не увидеть эту новую запись. Это может фактически вызвать ваш кусок кода для создания нового сообщения, когда оно уже было размещено.

Исправление состоит в том, чтобы заставить WordPress очищать кэш записи, выглядит так:

try {
  $asPosts = array();
  $asPosts = @ wp_get_recent_posts(1);
  foreach($asPosts as $asPost) {break;}
  @ delete_post_meta($asPost['ID'], '_thwart');
  @ add_post_meta($asPost['ID'], '_thwart', '' . date('Y-m-d H:i:s'));
} catch (Exception $e) {}
$asPosts = array();
$asPosts = @ wp_get_recent_posts(1);
foreach($asPosts as $asPost) {break;}   
$sLastPostDate = '';
@ $sLastPostDate = $asPost['post_date'];
$sLastPostDate = substr($sLastPostDate, 0, strpos($sLastPostDate, ' '));
$sNow = date('Y-m-d H:i:s');
$sNow = substr($sNow, 0, strpos($sNow, ' '));
if ($sLastPostDate != $sNow) {
  // No post today, so go ahead and post your new blog post.
  // Place that code here.
}

Первое, что мы делаем, получаем самую последнюю запись. Но нам все равно, если это не самый последний пост или нет. Все, что мы получаем, - это получение одного идентификатора поста, а затем мы добавляем скрытое настраиваемое поле (таким образом подчеркивание, с которого оно начинается) с именем

_thwart

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

Как только это произойдет, мы также снова используем wp_get_recent_posts (1), чтобы мы могли видеть, не является ли самая последняя запись сегодняшней датой. Если нет, тогда мы можем добавить в него какой-то контент. (Или, если вы хотите, чтобы капал только каждые 72 часа и т. Д., Вы можете немного изменить это здесь.)

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