WordPress使用多个会话写缓存问题

时间:2010-04-20 01:38:32

标签: wordpress session caching

我正在使用WordPress中的内容dripper自定义插件,我的客户要求我构建。他说他希望它能抓住一个页面查看事件,如果它是一天中的正确时间(自上次发布后24小时),则从资源文件中提取并输出另一个帖子。他还需要它来提升一个标志并阻止其他会话触发相同的代码片段。因此,举起某种旗帜,说“我发帖子,离开其他过程”,然后它发出那个帖子并再次发布旗帜。

然而,最奇怪的事情发生在加载时,多个会话通过页面查看命中网站。它正在开火而不是一个帖子 - 它随机地做了1,2或3个额外的帖子,每个人认为这是发布的正确时间,因为它是在最后一个帖子之后的24小时。因为它有点随机,我猜这个问题是某种写缓存,其他会话直到几微秒才会看到凸起的标志。

插件通过简单地使用WordPress中的update_option()API写入wp_options表来提升“标志”。其他用户会话应该使用get_option()读取该值并查看该标志,然后不运行创建帖子的那段代码,因为给定的会话已经在执行它。然后,完成后,我降低标志,其他会话继续正常。

但它正在做的是让其他会议进入。

为了完成这项工作,我使用了add_action('loop_start','checkToAddContent')。关于该功能的奇怪之处在于它在页面上不止一次被调用,实际上一些插件可能会调用它。我不知道是否有更好的事件可以勾选。即便如此,即使我发现一个只在页面视图上运行一次的事件,我仍然有多个会话要与之竞争(可能同时查看该页面的不同用户)并且我只希望触发一个给定的会话帖子到期时的内容发布。

我想知道是否有任何WordPress插件开发者可以建议另一个事件挂钩来锁定,并找出另一种方法来提升所有会话将看到的标志。我的意思是,我可以在PHP中使用共享内存API,但许多托管计划已禁用。无法使用cookie或会话var,因为这只是一个会话。关于托管计划可能有效的唯一事情是将文件作为标志删除。如果文件存在,则一个会话具有该标志。如果该文件不存在,则其他会话可以尝试获取该标志。当然,我可以使用文件路径,但在我看来它有点不成熟,我想知道我能用WordPress做些什么。

2 个答案:

答案 0 :(得分:1)

关键可能是在数据库中为“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()和时间戳是否属于您。如果是,滴水。

SELECT sessionid FROM table WHERE postcategory =“$ postcategory” AND时间戳= $ ts AND sessionid =“$ sid”

答案 1 :(得分:0)

问题是这样的,即使来自同一会话(同一访问者)的页面请求,也可能出现来自不同访问者的页面请求。它的工作原理如下:

  • 如果您正在进行内容播放,那么页面请求可能就是您使用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.
}

我们要做的第一件事是获取最新的帖子。但我们并不关心它是否不是最近的帖子。我们得到的只是获得一个帖子ID,然后我们添加一个隐藏的自定义字段(因此它的下划线开头)称为

  

_thwart

...就像在,通过将一些数据发布到不太CPU的数据库来阻止写缓存。

一旦到位,我们再次使用wp_get_recent_posts(1),以便我们可以查看最近的帖子是否不是今天的日期。如果没有,那么我们很清楚滴下一些内容。(或者,如果你只想每72小时滴一次,等等,你可以在这里改变一下。)