Vypnutí cache pro konkrétní presenter

MikKuba
Člen | 45
+
0
-

Ahoj,

Koukal jsem se po fóru, ale nenašel nic, co by mě pomohlo vyřešit problém.
Potřeboval bych, zda mohu nějakým způsobem pro daný presenter zakázat cache? Důvod je takový, že často dochází v rámci rozmezí jednotek sekund k tomu, že na konkrétní URL přistupuje třeba 30 uživatelů zaráz a z toho polovina hlásí při prvním načtení chybu, většinou po refreshi už jim to jde, případně druhý refresh nebo dokonce pomocí CTRL SHIFT + R. Tak nějak z toho viním cache.

Většinou je odkaz nový a docela jednorázový, před tím jednorázovým připojení uživatelů se daná URL necachuje vůbec nebo jen jednou (autor URL jednou na ni přistoupí a vyzkouší).

Proto bych rád zkusil vypnout cache pro daný presenter (ten je vždy stejný pro danou URL, jen potom volá z DB jiné údaje).
Nebo se s touto teorií mýlím úplně a problém bude jinde?

Děkuju!

David Matějka
Moderator | 6354
+
0
-

Jakou cache chceš vypnout?

Jakou chybu to hlásí?

Nebude spíše problém to, že to nezvládne 30 uživatelů naráz a potřeboval by si to cachovat?

MikKuba
Člen | 45
+
0
-

@DavidMatějka
Mám ExercisePresenter, který načítá jen jednu komponentu

protected function createComponentExerciseView()
 {
  $exercise = $this->exerciseView->create($this->getParameter('key'), $this->getParameter('id'), $this->getParameter('userKey'));
  return $exercise;
 }

S tím že při prvním načtení není v URL ten userKey. Na základě toho se má tedy připravit formulář s jedním inputem a po jeho vyplnění se načte druhý formulář a nový view, předtím ale dojde redirect na URL ve které už je i ten userKey.

Teď se ale dívám, že v logu erroru s PHP notice je, že nejde načíst hodnotu která měla přijít z databáze a potom error, na kterém nejspíš všichni hlásí chybu je, že chybí při odeslání prvního formuláře exercises_id, které ale má přijít v tom parametru z presenteru (bere se z URL).

Při zpětné kontrole ale zjišťuju, že musím tu celou render() metodu upravit, aby se jednak načítaly proměnné jen když jsou pro to opravdu data a poté otestuju znovu.

Jen mě nenapadá, jak bych mohl sám efektivně nasimulovat otevření jedné stránky 30×, když to zkusím na jediném PC a otevřu takto odkaz na X kartách, tak se to všude načte. Ten problém ale vzniká, když to zaráz zkouší více počítačů..

MikKuba
Člen | 45
+
0
-

Může mít databáze problém vytáhnout v rámci 2 sekund 30 stejných requestů? To je blbost, ne?

Nejčastější error podle logu je, že uživateli se patrně první krok (entry.latte) načte v pohodě a v momentě, kdy to uloží, tak se snaží provést uložení do DB, kde ale chybí ID pro exercises_id, které nesmí být NULL, takže databáze vyhodí error.

Zpracování v ExerciseView:

public function saveEntry($form){
 if($this->data->validity_from && $this->data->validity_to){
  if($this->data->validity_from > date('Y-m-d H:i:s')){
   return $this->onErrorAccess('Ještě není možné zahájit test');
  }
  if($this->data->validity_to < date('Y-m-d H:i:s')){
   return $this->onErrorAccess('Vypršela platnost, po kterou je možné test zahájit');
  }
 }
 $values = $form->getValues();
 $post = $this->exercisesManager->addResults([
   'exercises_id' => $this->id,
   'name' => $values->name,
   'key' => Random::generate(8, '0-9a-z'),
   'points' => 0,
   'max' => 0,
   'started' => date('Y-m-d H:i:s')
 ]);
 $this->onSubmitEntry($post->key);
}

Do $this->data se načítají data při načtení view:

interface IExerciseView
{
    /**
     * @param string $key
     * @param int $id
     * @param string $userKey
     * @return ExerciseView
     */
    function create($key, $id, $userKey);
}

class ExerciseView extends Control{
 function __construct($key, $id, $userKey, Context $db, ExercisesManager $exercisesManager)
  {
   $this->key = $key;
   $this->id = $id;
   $this->userKey = $userKey;
   $this->db = $db;
   $this->exercisesManager = $exercisesManager;
   $this->data = $this->getData()->fetch();
   $this->questions = $this->getQuestions();
 }
}

Načtení dat je jednoduchá funkce, manager obsahuje pouze SQL dotaz na vytažení podle URL_KEY a ID :

private function getData()
        {
                return $this->exercisesManager->getExercise($this->key, $this->id);
        }

Na první pohled mi tyto funkce nepřijdou chybné a taky nejsou, když testuji. Ale vypadá to, že když naráz přijde na jednu URL 20–30 lidí zároveň, tak jakoby se některým nenačetla data do $this->data.

Je to nějak možné? Příznakem toho je, že se mnohdy ve stejný čas ukládání exception, že ukládám exercises_id = NULL, tak se generuje PHP notice, že se nepodařilo načíst některý z atributů exercise, které už by mělo být natažené právě do $this->data a vypsáno někde v šabloně nebo použito v PHP pro výpočet.

David Matějka
Moderator | 6354
+
0
-

Jestli to mas na nejakym sdilenym hostingu, tak tam pravdepodobne budou mit nejaky limity – at uz pocet requestu na php, tak pocet omezeni spojeni k db.

a k te chybe – odkud a jakym zpusobem predavas to id, ktere pak chybi?

MikKuba
Člen | 45
+
0
-

@DavidMatějka Vše běží na Wedosu, kde se tváří že by to mělo být stavěno na vysoký traffic, klidně tisíc uživatelů. Zkusím napsat na podporu, ale bojím se že nepochodím, protože dostávám chybu v aplikaci, takže mi moc nepomůžou.

Id předávám z presenteru, to jsem zapomněl přidat do posledního příspěvku, bylo to v prvním.

protected function createComponentExerciseView()
 {
  $exercise = $this->exerciseView->create($this->getParameter('key'), $this->getParameter('id'), $this->getParameter('userKey'));
  return $exercise;
 }

Tedy URL je při prvotním načtení ve formatu domena.cz/we545wef1e/e22, s tím že po přihlášení je URL domena.cz/we545wef1e/e22/dgs5sdd, tedy poslední parametr userKey se generuje až po přihlášení a proběhne pak redirect na URL s tím userKey na konci.

Podle stopování errorů mi z toho vychází, že při hromadném (a možná ne vždy hromadném) otevření jedné URL se nějak nenačte ten druhý parametr ID (následující vždy po písmenu „e“ v URL), takže se pak ani toto ID nepropíše při ukládání do databáze, kde to je povinné.
Možná zkusit ve View nějakou kontrolu, že pokud neexistuje $this->id, pokusit se ho znovu nabrat z requestu pomocí Nette\Request utility?

David Matějka
Moderator | 6354
+
+2
-

ve vygenerovanem exception HTML od tracy bys mel videt treba URL, na ktere se chyba stala, takze uvidis, jestli v URL bylo to ID.

jinak u wedosu fakt necekej, ze bys za tech par desitek korun ziskal hosting, ktery vydrzi nejaky napor uzivatelu.