Есть такая вот задачка:
Есть Н массивов, которые нужно хранить между сессиями (в кеше - apc).
При любом запросе поменяться может любой из них (хоть все), и после окончания работы изменения необходимо внести в кеш обратно.
В это же время любой запрос может считывать один из массивов и изменять его.
Вопрос такой: как синхронизировать доступ на чтение к этим массивам, чтобы при обратной записи в кеш данные не терялись?
Спустя 57 минут, 13 секунд (22.12.2011 - 01:34) vital написал(а):
Локи\очереди
Спустя 2 минуты, 47 секунд (22.12.2011 - 01:37) vital написал(а):
т.е. когда первый процесс берет данные из кеша, пусть устанавливает некий флаг, что данные сейчас в работе и снимает этот флаг, когда закончит.
Следующий процесс проверяет, есть ли этот флаг, если нету см начало, если есть - добваляется в очередь и ждет окончания, след процесс..
Следующий процесс проверяет, есть ли этот флаг, если нету см начало, если есть - добваляется в очередь и ждет окончания, след процесс..
Спустя 1 час, 11 минут, 25 секунд (22.12.2011 - 02:49) saxon написал(а):
Такая операция блокировки не будет атомарной и не сработает.
Сделал пока через flock и файл блокировки на диске
Открываю файл и пытаюсь его залочить. вроде работает, насколько могу судить.
но как-то ужасно и странно
Сделал пока через flock и файл блокировки на диске
Открываю файл и пытаюсь его залочить. вроде работает, насколько могу судить.
но как-то ужасно и странно
Спустя 15 часов, 2 минуты, 25 секунд (22.12.2011 - 17:51) SlavaFr написал(а):
а что если в этом случае просто отказатся от собственного кеширования и использовать кеаш базы даннык?
Спустя 2 минуты, 36 секунд (22.12.2011 - 17:54) Arni написал(а):
Проверял под нагрузками. Ни разу сбоя не дало.
<?php
//////////////////////////////////////////////////////////////////////////////////////////////////// /////
// COPYRIGHTS © $ALEXA-CMS PHP TEAM //
// PRODUCT : CMS(CONTENT MANAGEMENT SYSTEM) //
// LICENSE : Berkley Software Distribution //
// WWW: www.alexa-cms.com //
// E-MAIL : support@alexa-cms.com //
// The file description : Cache system //
//////////////////////////////////////////////////////////////////////////////////////////////////// /////
/* =================================================================================================== ##
## Class CACHE_File ##
## =================================================================================================== */
class CACHE_File implements CACHE_ICache
{
private $path;
public function __construct($path = '')
{
$this->path = $path;
}
public function save($value, $valueID)
{
return file_put_contents($this->pathCache($valueID).md5($valueID),serialize($value),LOCK_EX);
}
public function load($valueID, $time)
{
$file_name = $this->getPathCache($valueID).md5($valueID);
if (file_exists($file_name) && ((filemtime($file_name) + $time) > time())){
return unserialize(file_get_contents($file_name));
}else{
return false;
}
}
public function delete($valueID)
{
$file_name = $this->getPathCache($valueID).md5($valueID);
unlink($file_name);
}
private function pathCache($valueID)
{
$md5 = md5($valueID);
$first_literal = array($md5{0}, $md5{1}, $md5{2}, $md5{3});
$path = $this->path;
foreach ($first_literal as $dir) {
$path .= $dir.'/';
if (!file_exists($path)){
if (!mkdir($path, 0777)) return false;
}
}
return $path;
}
private function getPathCache($valueID)
{
$md5 = md5($valueID);
$first_literal = array($md5{0}, $md5{1}, $md5{2}, $md5{3});
return $this->path.implode('/', $first_literal).'/';
}
}
?>