Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CacheDecorator pro WebService #44

Closed
5 tasks done
JindrichPilar opened this issue Jan 1, 2015 · 12 comments
Closed
5 tasks done

CacheDecorator pro WebService #44

JindrichPilar opened this issue Jan 1, 2015 · 12 comments

Comments

@JindrichPilar
Copy link
Member

Ve vetsi aplikaci, nebo aplikaci hodne modulovane (pouzivajici framework) se casto stava ze se vola nektera funkce nekolikrat a diky slozeni z jednotlivych komponent je ponekud slozitejsi si jiz prenesena data predavat.

Priklad:

  • Login //Taha data
  • Event onLoggedIn - aktualizuj udaje pro prihlaseneho uzivatele //Taha data
  • Dlouho nebyl aktualizovan seznam vedoucich //Taha data
  • Panel na na boku stranky (samostatny plugin) //Taha data
  • Controller //Taha data

Prvni request bude trvat 150ms+ (stazeni wsdl)
Kazdy dalsi 60ms+
Coz dohromady dava 390ms misto 150.
Samozrejme za predpokladu ze je dobre pripojeni, Skautis je nezatizeny a slape rychle.

Coz samo o sobe neni prilis dlouho, ale kdyz se k tomu pricte prace DB, nejake to sahnuti na soubory v kombinaci s mobilnim pripojeni a programatorem zacatecnikem (nebo nemajicim cas optimalizovat) je z toho par sekundovy pozadavek, coz uz je problem.

Navrhoval bych pouziti cache pro jiz prenesena data, podobne jako maji ruzna ORM. Tak aby WebService pri stejnych requestech vracela odpoved z cache.

Implementaci bych navrhl pomoci decorator paternu, aby se dala tato funkce jednoduse pridat a jinak neprekazela.

V knihovne by meli existovat 2 predpripravene Cache implementace

  • Array - pro 1 beh PHP
  • Session - po dobu session (Vyuzivajici jiz existujici SessionAdapterInterface)

Otazky ktere je potreba prvni zodpovedet:

  • Patri to jeste do knihovny?
  • Jak by to fungovalo s batch requesty issue BatchRequest SOAP #29?
  • Mela by se vytvorit WebServiceInterface, zrusit dedeni od \SoapClient a ten pouzit interne?
  • Vhodny zpusob vytvoreni klice.
  • Bezpecnost, jak nevracet data neopravnenemu uzivateli (spolehlive) - spolehat se ze uzivatel zavola odhlasovaci metodu / vyzadovat alespon jeden uspesny pozadavek na Skautis?

Ukazka

class WebServiceCacheDecorator implements WebServiceInterface
{

   /**
     * @var Skautis\Wsdl\WebService
     */
   protected $webService;

   /**
    * @var Skautis\CacheInterface
    */
   protected $cache;

   public function __get($functionName, $args)
   {
      if (isset($args['skautis_cache']) && $args['skautis_cache'] === false) {
          unset($args['skautis_cache']);
          return parent::__get($functionName, $args);
      }

      $sargs = $args; 
      ksort($sargs); 
      $jsonArgs = json_encode($sargs);

      $hash = hash($functionName . $jsonArgs);

      if ($this->cache->has($hash)) {
          return $this->cache->get($hash);
      }
      else {
          return parent::__get($functionName, $args);
      }
   }
}
@sinacek
Copy link
Member

sinacek commented Jan 2, 2015

Podle mě tam trvalé cache uložiště mezi spojeními nepatří do této knihovny. To ať dělá každý ve svém modelu. Ta cache pro jeden běh PHP mi příjde vhodná, ale jen pro některé služby. Tím by se vyřešili i další otázky jako predávání dat pouze oprávněné osobě, klíč( např: function . $args).

Ještě mě napadlo, jestli není lepší tedka dotáhnout verzi 2.0 do stabilního stavu s popisem apod a až pak tam dodělavat další vychytávky. Zatím by se dala už prezentovat a testovat verze 2.0 a vývoj by bežel už na další verzi

@JindrichPilar
Copy link
Member Author

trvalé cache uložiště mezi spojeními nepatří do této knihovny

Byl jen navrh toho co se da udelat s jiz existujicimi komponentami. Urcite staci zakladni decorator pro 1 request, dodelat cache je pak trivialni pro kohokoliv.

ale jen pro některé služby
klíč( např: function . $args)

Tech sluzeb je spousta a muselo by se neustale upravovat se zmenama tech sluzeb, navic rozhodnout co je a co uz neni cachovatelne by take bylo prijnemensim sporne. (takhle z hlavy me napada adresa strediska, zbytek tam jsou spousty osobnich informaci predevsim deti)
Jako nejbezpecnejsi, neujdrzitelnejsi a zaroven nejefektivnejsi bych videl:

  • aby cache vracela data vyzaduje alespon 1 uspesny pozadavek na server Skautisu
  • klic(functionName, args, sessionToken nebo userID)

jestli není lepší tedka dotáhnout verzi 2.0 do stabilního stavu s popisem apod

To dost mozna je, ale minimalne cast tohoto navrhu (WebServiceInterface) je dost velka zmena na to aby byla zahrnuta do 2.0
Pred vypustenim 2.0 je potreba mit hotove veskere zmeny v architekture. Popis, dokumentace etc. je u takovychto zmen, ackoliv stejne dulezite, az to posledni, Napr. je potreba rozhodnout jestli chceme implementovat batch requesty #29, ktere pravdepodobne budou vyzadovat nejake vetsi zmeny take.
Mam ted do skoly spoustu veci, ale az budu mit volneji tak se pustim i do dokumentace.

@sinacek
Copy link
Member

sinacek commented Jan 2, 2015

Byl jen navrh toho co se da udelat s jiz existujicimi komponentami. Urcite staci zakladni decorator pro 1 request, dodelat cache je pak trivialni pro kohokoliv.

Jako návrh to beru, proto jsem k nemu dopsal svůj pohled.

klic(functionName, args, sessionToken nebo userID)

Asi jsem to myslel tak, že by ani nebylo potreba tam resit jeden fungujici pozadavek nebo sessionToken. Myslel jsem to tak, že pokud se při načtení jedné stránky zeptám 2x na detail jednotky s ID 123, tak si to tu první odpověd uschová jen do pole například pod klic unitDetail_ID_123 a z koncem načítání stránky se vymaže i to docasne pole. To co navrhuju je cache na velmi krátkou dobu, ale může podle mě pomoc a zároveň nijak neohrozit uník dat.

verze 2.0

pokud tam mají být ještě velké změny, tak můžem počkat, jen bych nerad, aby jsme to tak dlouho vylepšovali, až to nevydali... ale to zatím nehrozí.

@JindrichPilar
Copy link
Member Author

To co navrhuju je cache na velmi krátkou dobu, ale může podle mě pomoc a zároveň nijak neohrozit uník dat.

To je pravda, ale implementaci cache muze pridat kazdy sam a nemas nad ni zadnou kontrolu, proto bych, pro jistotu, pridal nejakou kontrolu do WebServiceCacheDecorator. Rad bych aby knihovna sama o sobe zajistovala urcitou uroven bezpecnosti, protoze jeji ucel je pristupovat k sluzbe jejiz obsah je spousta osobnich informaci vcetne fotek, veku, adres a telefonich cisel. Coz v kombinaci s tim ze se da predpokladat ze strediska nebudou najimat profesionalniho vyvojare muze vest ke slusnemu problemu.

@sinacek
Copy link
Member

sinacek commented Jan 2, 2015

Souhlasím s tím, že si nebudou najímat profesionála, ale to podle mě povede jen na to, že to nebudou mít cachované a většina z nich bude využívat WS na svém webu hlavně na přihlášení. Příjde ti to cachování pouze v rámci požadavku jako málo efektivní? nevím jestli tedka uplne chapu, kam míříš

@xificurk
Copy link
Contributor

xificurk commented Jan 2, 2015

Návrh na zavedení WebServiceInterface se mi líbí - ideální by bylo, kdyby definoval nějakou čitelnější metodu pro SOAP cally, ta magie v __call() se mi právě moc nelíbí.

Taky si myslím, že kešování na delší dobu než jeden request do této knihovny nepatří. A ani v případě kešování jen v rámci jednoho requestu si nejsem jistý, jak to rozumně implementovat - jak by se nakešované údaje invalidovaly? Co když si nejprve vyžádám ze skautISu nějakou hodnotu, pak ji dalším voláním změním a pak zas opět jiná komponenta webu bude chtít to samé číst?

@sinacek
Copy link
Member

sinacek commented Jan 2, 2015

jak by se nakešované údaje invalidovaly?

Například zavolanim metody clearCache

Já si tím cachováním v rámci požadavku, také nejsem jistý, ale pokud nějaké, tak podle mě maximálně toto.

@xificurk
Copy link
Contributor

xificurk commented Jan 2, 2015

@sinacek To se mi právě vůbec nelíbí - pak na jednom místě po změně dat zapomeneš zavolat clearCache() a máš zaděláno na příjemně strávený víkend debugováním chyby, která se dost těžko reprodukuje (A je klidně možné, že uběhne dlouhá doba než se vůbec poprvé projeví).

@JindrichPilar
Copy link
Member Author

nevím jestli tedka uplne chapu, kam míříš

Cachovani v ramci pozadavku mi prijde pro drtivou vetsinu dostatecne efektivni i bezpecne.
To kam mirim vypada asi takto:
new WebServiceCacheDecorator(WebServiceInterface $webService, CacheInterface $cache);
CacheInterface je tam proto aby si kazdy mohl dodat jakoukoliv implementaci chce, nad tou nema knihovna kontrolu. Proto bych pro jistotu implementoval nejaky overovaci mechanismus primo do WebServiceCacheDecorator.

Návrh na zavedení WebServiceInterface se mi líbí - ideální by bylo, kdyby definoval nějakou čitelnější metodu pro SOAP cally, ta magie v __call() se mi právě moc nelíbí.

S tim naprosto souhlasim, Pekny interface by vypadal treba takto:
WsdlManager::getService($name);
Skautis::getService($name);

jak by se nakešované údaje invalidovaly?

Pocital jsem s zadnou automatickou invalidaci. Doba cachovani zalezi na implementaci cache => neni zalezitost teto knihovny.
A pro komponenty co vyzaduji aktualni data jsem v kodu v prispevku navrhl $args['skautis_cache'].

Muj cil neni aby knihovna implementovala cache nybrz mela zaklad pro to aby se dal jednoznacne implemnetovat. Treba uz kvuli Nette a Symfony balickum. => jednotny zaklad pro Decorator.

zapomeneš zavolat clearCache()

Pokud nekdo pise aplikaci ktera intenzivne meni data proste ty cache nepouzije. Proto je navrhuji pomoci decoratoru. Navic kolik % aplikaci data upravuje?

@sinacek
Copy link
Member

sinacek commented Jan 2, 2015

@xificurk to máš pravdu, že to může být matoucí. Je to problém každé cache

@JindrichPilar původně jsem myslel, že tam chceš přidávat i implementaci rovnou do knihovny, ale tedka uz jsem to pochopil a jsem klidně pro interface, který si každý naimplementuje jak bude chtít a jen pokud bude chtít

@JindrichPilar
Copy link
Member Author

Ano, navrhoval jsem i nejakou zakladni implementaci tohoCacheInterface. Napriklad pomoci pole pro ten 1 request. S tim ze aby to clovek pouzil musi ten decorator rucne pouzit. Hlavne cache pro ten 1 request bude pravdepodobne ta nejvice vyuzitelna varianta a tak by si zaslouzila misto primo tady.

@sinacek
Copy link
Member

sinacek commented Jan 2, 2015

Něco základního bych sem klidně dal, ale právě složitější cache operace jsou už příliš vzdálené a bude dobré jen pro ně něchat prostor, ale neřešit je.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants