У нас есть очень дорогое вычисление, которое мы хотели бы кэшировать. Итак, мы делаем нечто подобное:
my $result = $cache->get( $key );
unless ($result) {
$result = calculate( $key );
$cache->set( $key, $result, '10 minutes' );
}
return $result;
Теперь, во время calculate($key)
, прежде чем мы сохраним результат в кэше, приходит несколько других запросов, которые также начинают выполняться calculate($ key)
, и производительность системы страдает, потому что многие процессы вычисляют одно и то же.
Идея: Давайте поместим в кеш флаг того, что вычисляется значение, чтобы другие запросы просто ждали завершения этого единственного вычисления, чтобы все они использовали его. Что-то вроде:
my $result = $cache->get( $key );
if ($result) {
while ($result =~ /Wait, \d+ is running calculate../) {
sleep 0.5;
$result = $cache->get( $key );
}
} else {
$cache->set( $key, "Wait, $$ is running calculate()", '10 minutes' );
$result = calculate( $key );
$cache->set( $key, $result, '10 minutes' );
}
return $result;
Теперь это открывает совершенно новую банку червей. Что, если $$ умрет до того, как установит кеш. Что если, что если... Все они решаемы, но поскольку в CPANнет ничего, что бы это делало (в CPAN есть что-то для всего), я начинаю задаваться вопросом:
Есть ли лучший подход? Есть ли особая причина, например. Классы Perl Cache
и Cache::Cache
не предоставляют такого механизма? Есть ли проверенный и верный шаблон, который я мог бы использовать вместо этого?
Идеальным был бы модуль CPAN с пакетом debian, который уже находится в сжатии, или момент озарения, когда я вижу ошибку своего пути... :-)
РЕДАКТИРОВАТЬ: с тех пор я узнал, что это называется Паническое бегство кэшаи обновили заголовок вопроса.