使用服务器端事件[通过phpfastcache]丢失缓存项

时间:2017-09-06 11:32:56

标签: php caching phpfastcache

我正在使用Server-Sent Events为用户打印消息。

在无限循环中,每隔10秒我检查缓存中是否有任何新项目要广播:

$messages_to_broadcast = $this->_cache->getItemsByTag('inbox_message');
foreach ($messages_to_broadcast as $key => $_message) {
    $_message = $_message->get();
    if($_message->recipient == $this->_user_id || $_message->recipient == 0){
        if(!is_null($html = \CRM\Engine\MessagingService::getMessageToBroadcast($_message)))
        {
           echo "event: $_message->type \n";
           echo "data:{\n";
           echo "data:\"message_html\": \"$html\" \n";
           echo "data:}\n\n";
           $this->send_keepalive = false;
           $this->_cache->deleteItem($key);
        }
    }
}

不定期,有一个事件,它将消息保存到缓存中:

$_cache_this = self::$_cache->getItem("message_".$_message->id);
if(!$_cache_this->isHit()){
    $_cache_this->set($_message)
        ->expiresAfter(600)
        ->addTag('inbox_message');
    self::$_cache->save($_cache_this);
}

问题在于,当我在缓存中检查新项目的无限循环时,我得到空数组。当我重新加载页面或浏览器重新连接到服务器端事件流时,项目将出现在缓存中。我在这里缺少flush方法吗? 我正在使用files作为缓存方法。

\phpFastCache\CacheManager::setDefaultConfig(array(
    "path" => DIR_TMP
));
global $cache;
$cache = \phpFastCache\CacheManager::getInstance('files');

3 个答案:

答案 0 :(得分:2)

在循环中,必须使用PhpFastCache的detachItem方法来强制其获取正确的值。

这里有个例子:

while (1) {
    $cache = $this->cacheService->getCache();
    if (null !== $cache) {
        try {
            $item = $cache->getItem('my_key');
            if ($item->isHit()) {
                echo "event: message\ndata: $item->get()\n\n";
            }
            $cache->detachItem($item);
        } catch (InvalidArgumentException | PhpfastcacheInvalidArgumentException $e) {
            $this->logger->error(
                'There has been an error when getting cache item: '
                .$e->getMessage().' - '.$e->getFile().' - '.$e->getLine()
            );
        }
    }

    ob_flush();
    flush();

    if (connection_aborted()) {
        break;
    }
    sleep(1);
}

我在这里打开了一个问题,要求更多文档:https://github.com/PHPSocialNetwork/phpfastcache/issues/687

答案 1 :(得分:1)

Phpfastcache正在将缓存项静态存储(实际上,确切的定义是“缓存”)在缓存后端对象中。因此,有效地,您需要使用detachItem()方法或clear()释放对象以清空缓存。

this issue所述,我将尽快更新Wiki,以阐明永久性CLI脚本的行为。

答案 2 :(得分:0)

有一段时间你问过这个,但通常你只能按标签抓取缓存中的项目,还没有看到让你获得所有缓存条目的方法。

$entries = $cache->getItemsByTag('inbox_message')

$entries现在将保留您的所有物品。

看看这里: https://github.com/PHPSocialNetwork/phpfastcache/blob/final/docs/examples/tagsMethods.php 在那里你可以看到一个关于使用的完整例子。