Jak na callback dependency v cache?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
CZechBoY
Člen | 3608
+
0
-

Zdravím,
potřebuji cronem ukládat data do cache a na webu je návštěvníkovi prostě jen vytáhnout z cache.
Tak jsem si ke každé metodě přidal parametr $forceRecache = false a v cronu je volám s parametrem $forceRecache = true.
Použil jsem dependency typu CALLBACK, kdy prostě vrátím proměnnou $forceRecache.

Kod ve zkratce nějak takto:

public function getData($refreshCache = false)
{
	$this->cache->wrap(function () {
		// náročné tahání dat
	}, array (
		Cache::CALLBACKS => [[[$this, 'simplyReturn'], !$forceRecache]],
		Cache::EXPIRATION => DateTime::from('+10 minutes')
	));
}

Problém je, že closure nelze serializovat.

Lze to vyřešit nějak lépe?
Díky

castamir
Člen | 629
+
0
-

Asi bych zvolil následující koncept:

  • použil bych spíš cache->load(key, $fallback) (chování mi přijde podobné, ale load víc přímočarý, čitelný)
  • použil bych nějaký společný tag
  • cron by automaticky invalidoval podle tagu
CZechBoY
Člen | 3608
+
0
-

On ten load a wrap dela to stejny mi prijde.. Jen u load je moznost key. (vlastne to mam ted pres load, ale obaleny v moji funkci jeste)
Aktualne jsem to vyresil tak, ze kdyz volam tu funkci s parametrem precachovani a smazu cache. Potom uz klasicky pokus o nacteni dat z cache, pokud neexistuje tak se pregeneruje.
Myslim ze jsem asi prisel o atomicitu, ale to nemam cas ted resit :-(

Ma moje reseni nejakej rozdil oproti tem tagum? Tzn misto tagu rovnou smaznu cache podle klice…

castamir
Člen | 629
+
0
-

Invalidace pomocí tagů ti řeší jeden typ problému a tím je konzistence dat. Nevím, zda je to ve Tvém případě podstatné, či nikoliv.

CZechBoY
Člen | 3608
+
0
-

No data by mely bejt jen jedny pro dany klic. Pokud budou o 10 minut starsi tak to zas tak nevadi… Ale lepsi by byly rovnou ty pregenerovana data.

castamir
Člen | 629
+
0
-

Ještě mě napadlo, že cron ti může volat čistě jen metodu save($key, $data, $dependencies), čímž si možná trošku pomůžeš…

CZechBoY
Člen | 3608
+
0
-

Jo, ale kde ty vsechny veci zjistim :-)

Ziskani dat ze zacachovany. Jedine to presunout do jiny private metody, abych neduplikoval kod.

castamir
Člen | 629
+
0
-
<?php

namespace App;

use Nette\Caching\Cache;

class Service
{
    /** @var Cache */
    private $cache;

    private $key;



    public function load($args)
    {
        return $this->cache->load($this->key, function($dependencies) use ($args) {
            $dependencies[Cache::EXPIRATION] = '10 minutes';
            return $this->doSomeSeriousMath($args);
        });
    }



    public function store($args)
    {
        $data = $this->doSomeSeriousMath($args);
        $this->cache->save($this->key, $data, [Cache::EXPIRATION => '10 minutes']);
    }



    private function doSomeSeriousMath($args)
    {
        return $args;
    }
}
CZechBoY
Člen | 3608
+
0
-

Jo, jasný no. Takhle jsem si říkal, že to je moc ukecaný a moc se mi natahuje počet veřejných metod (už tak ta třída má triliardu řádků, ale o to nebudu teď rozebírat).
Ten model obsahuje dejme tomu 15 metod, který chci cachovat. Takže bych musel pro každou metodu mít

  • 1 klíč do cache
  • 1 expiraci
  • 1 privátní metodu, která vrátí data

to se mi moc nelíbí, strašně ukecaný na to, co to má dělat :-(

S tím parametrem se mi to líbí, ikdyž to asi není zas moc pěkný takhle znásilňovat metodu na 2 věci…

Něco mezitim není?

castamir
Člen | 629
+
0
-

Beru zpět. Máš pravdu, že je to zbytečně ukecané. Tu store() metodu nepotřebuješ. Voláním load() v cronu dosáhneš toho stejného (prodloužíš expiraci). Klíč tím pádem máš na jednom místě, takže nemusíš mít ani konstanty.

CZechBoY
Člen | 3608
+
0
-

Ten load jen nacte data z cache pokud existuje; pokud ne tak nekde draze sezene a ulozi.
Ja potrebuju cronem prepsat „stary data“ a ty ulozit aby uz navstevnik webu mel rychle nactenou stranku z cache.

Ja to ted resim tak ze tu cache smaznu (pokud je vyzadano) a dal je chovani stejne jak pro obyc zobrazeni tak pro cron. Akorat se bojim toho, ze muze prijit request jeste mezi tema dvema operacema (smazani a znovunacteni+ulozeni).