[PHP/AJAX] alle objecten kwijt (traag)

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo,

Ik ben al een tijdje bezig met MVC in PHP, nu wou ik ook asynchrone requests integreren.
De vraag waarmee ik zit is dat wanneer ik een asynchrone request doe ik alle PHP objecten weer vanaf 0 af aan moet opnieuw bouwen wat wel een grote overhead geeft?

even een voorbeeld, wanneer ik naar volgende URL surf:
http://localhost/cms/Index/login
(module = Index, class = login, functie = __default())
krijg ik een aantal velden om me in te loggen


Wanneer ik een email adres en wachtwoord ingeef en ik op inloggen klik, wordt er een asynchrone request(ajax) gedaan naar volgende URL:
http://localhost/cms/Index/login/login.html
(module = Index, class = login, functie = login())

Hieraan worden met POST het emailadres en wachtwoord meegegeven.
Bij deze aanroep zal het login object weer volledig opnieuw aangemaakt worden vanaf 0, er zal dus terug in de cookie of sessie gekeken worden of de unieke code hierin overeenkomt met deze in de database, default taal wordt geladen, log objecten, nodige authentication wordt gedaan,...)

Dit zorgt volgens mij toch wel voor een hele hoop vertragingen. Voor het inloggen nu duurt het toch wel al een secondje of 2 vooralleer ik een bericht krijg met succesvol ingelogd of niet...

Kan dit verholpen worden? m.a.w. is het normaal dat voor elke asynchrone request alle objecten weer opnieuw worden opgebouwd? doen jullie dit ook zo?

Acties:
  • 0 Henk 'm!

  • plofkip
  • Registratie: Oktober 2002
  • Laatst online: 03-09 19:11
Gebruik ASP.Net Ajax, dan is je context gewoon beschikbaar :)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
kipusoep schreef op zondag 23 augustus 2009 @ 02:51:
Gebruik ASP.Net Ajax, dan is je context gewoon beschikbaar :)
ja dat kan wel goed zijn kan ook java session beans gebruiken en is het probleem ook verholpen, maar ik gebruik voor dit dus PHP.

Acties:
  • 0 Henk 'm!

  • Vinnienerd
  • Registratie: Juli 2000
  • Laatst online: 17:18
Kun je niet zelf een soort ASP viewstate in PHP maken? Of snap ik het dan weer niet? :P

Acties:
  • 0 Henk 'm!

  • Manuel
  • Registratie: Maart 2008
  • Laatst online: 17-09 14:28
Kan je eens gaan debuggen? Installeer eens Firebug in Firefox, zie je precies hoe lang 1 request eigenlijk duurt en vaak ook wel hoe je dat kan fixen.
kipusoep schreef op zondag 23 augustus 2009 @ 02:51:
Gebruik ASP.Net Ajax, dan is je context gewoon beschikbaar :)
Het kan aan mij liggen, maar ik zie nergens staan dat hij ASP.NET gebruikt..

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

@TS: Dit is inherent aan de opzet van PHP. Behalve een beetje caching naar schijf, database of memcache kun je hier weinig aan doen.

@Vinnienerd: Nee, dat kan niet zomaar.

@Manuel: Het gaat hier helemaal niet over de fysieke tijd dat een request duurt, maar over de acties die ondernomen worden. De opmerking mbt ASP.NET is wel degelijk relevant omdat ASP.NET, net als Java, een meer continue draaiend proces is waardoor objecten gewoon (kunnen) blijven bestaan buiten de context van een enkel request.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Eddy Dean
  • Registratie: November 2007
  • Laatst online: 16-09 15:20
Je kunt ook de objecten die het duurste zijn om aan te maken in de session zetten. Met name voor singletons is dit heel makkelijk, omdat die toch al hun eigen instance managen.

Wat gebeurt er trouwens allemaal achter de schermen dat dit 2 seconden duurt? Ben je indexen op cruciale kolommen in je database vergeten ofzo? No offence, maar als een authenticatiefunctie zo lang nodig heeft doe je waarschijnlijk iets fout.

Draai eens een profiler op je server, en kijk met een programma als wincachegrind waar zoveel tijd in gaat zitten.

Wat is zo bijzonder aan een asynchrone request dat dit probleem zich alleen dan voordoet?

Acties:
  • 0 Henk 'm!

  • plofkip
  • Registratie: Oktober 2002
  • Laatst online: 03-09 19:11
Eddy Dean schreef op zondag 23 augustus 2009 @ 11:00:
Je kunt ook de objecten die het duurste zijn om aan te maken in de session zetten. Met name voor singletons is dit heel makkelijk, omdat die toch al hun eigen instance managen.
Ja hoor, dat is lekker efficiënt wou je zeggen 8)7

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Zo werkt PHP eenmaal. Als het inladen van een pagina 2 seconden duurt dan doe je ergens anders gewoon iets verkeerd, dat ligt niet aan PHP zelf.

Acties:
  • 0 Henk 'm!

  • Manuel
  • Registratie: Maart 2008
  • Laatst online: 17-09 14:28
Janoz schreef op zondag 23 augustus 2009 @ 09:29:
@Manuel: Het gaat hier helemaal niet over de fysieke tijd dat een request duurt, maar over de acties die ondernomen worden. De opmerking mbt ASP.NET is wel degelijk relevant omdat ASP.NET, net als Java, een meer continue draaiend proces is waardoor objecten gewoon (kunnen) blijven bestaan buiten de context van een enkel request.
Aah oke, ik las het op een andere manier.. Dacht eerder van: "Gebruik dan ASP.NET"..
* Manuel pakt zijn boek en leest weer eens een stukje verder...

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Tja, php bestaat nu eenmaal niet meer buiten de aanroep, dus elke aanroep start vanaf 0.

Wat je wel kan doen is simpelweg de dingen gaan cachen / niet meer inladen.

Default taal kan je bijv gewoon cachen. Authenticatie hoef je bijv geen rechtenchecks bij te doen ( het gaat er toch enkel om of iemand mag inloggen of niet, zoja dan kan hij doorgestuurd worden naar een vervolgpagina die de rechten checkt )

Maar ik zou het eerst gewoon eens goed gaan profilen, want 2 sec voor enkel een authenticatie vind ik wel erg lang....

Acties:
  • 0 Henk 'm!

  • Eddy Dean
  • Registratie: November 2007
  • Laatst online: 16-09 15:20
kipusoep schreef op zondag 23 augustus 2009 @ 11:28:
[...]

Ja hoor, dat is lekker efficiënt wou je zeggen 8)7
Ja, best wel... Voor objecten die lang duren om te creëren is dat de enige oplossing. Het serializen en deserializen van objecten gaat redelijk snel. Waarom zou het opslaan van objecten in de session in PHP niet efficient zijn en in ASP.NET wel? Vanwege het serializen?
Wat stel je anders voor? Het uitbreiden van PHP met een echte session scope? Maak je dan ook even een application scope, als je toch bezig bent? Het zou wat mij betreft een welkome toevoeging in PHP zijn, maar zo is het op het moment nu eenmaal niet.

Of ben ik nu aan het reageren op een troll?

Mijn tip blijft het profilen van de applicatie, en de punten waar de meeste performance gaat zitten (grote kans dat het grootste deel van die twee seconden zit in een enkele functie), en dat punt verbeteren.

Acties:
  • 0 Henk 'm!

  • plofkip
  • Registratie: Oktober 2002
  • Laatst online: 03-09 19:11
Eddy Dean schreef op zondag 23 augustus 2009 @ 12:55:
[...]


Ja, best wel... Voor objecten die lang duren om te creëren is dat de enige oplossing. Het serializen en deserializen van objecten gaat redelijk snel. Waarom zou het opslaan van objecten in de session in PHP niet efficient zijn en in ASP.NET wel? Vanwege het serializen?
Nee in ASP.NET gebeurt dat ook helemaal niet. 8)7
Ook de viewstate moet je zo min mogelijk op leunen, omdat het heen en weer gestuurd moet worden, wat niet efficiënt is.
Maar ik denk dat je het met mij eens bent, dat als je überhaupt gaat overwegen objecten in de sessie te frommelen, je ergens anders al verkeerd bezig bent geweest.
Wat stel je anders voor? Het uitbreiden van PHP met een echte session scope? Maak je dan ook even een application scope, als je toch bezig bent? Het zou wat mij betreft een welkome toevoeging in PHP zijn, maar zo is het op het moment nu eenmaal niet.
Nee, ik heb namelijk al lang voor ASP.NET gekozen i.p.v. PHP, om onder andere dit soort 'problemen'.
Of ben ik nu aan het reageren op een troll?
Nee, maar we raken wel een klein beetje offtopic met deze discussie ben ik bang.

[ Voor 14% gewijzigd door plofkip op 23-08-2009 13:10 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
bedankt allemaal voor de tips.

Ik heb met firebug wat zitten te profileren:

De ajax aanroep duurde 1.20s gaf firebug aan.

Om te testen aan waaraan dit ligt heb ik een simpele asynchrone request gedaan naar een hele simpele php pagina waar enkel het volgende instaat:
code:
1
2
3
<?php
echo "test";
?>


deze echo wordt dan met een alert uitgeschreven...
Ook dit heb ik even met profilen bekeken en de aanroep duurde nog steeds 1.0sec

Het kan dus niet liggen aan mijn php-scripts want ook voor dit zeer simpele script duurde het 1sec vooralleer de volledige request afgehandeld was.

Mij lijken deze tijden toch niet echt normaal ofwel?

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Eddy Dean schreef op zondag 23 augustus 2009 @ 12:55:
[...]
Ja, best wel... Voor objecten die lang duren om te creëren is dat de enige oplossing. Het serializen en deserializen van objecten gaat redelijk snel. Waarom zou het opslaan van objecten in de session in PHP niet efficient zijn en in ASP.NET wel? Vanwege het serializen?
Wat stel je anders voor?
Cachen...

Hij heeft het over default taal etc die geladen wordt, dat wil je echt niet in je session object hebben zitten.
Session objecten worden bij elke session_start gedeserialised en aan het einde weer geserialised.

Je wilt echt niet bij elke pagina aanroep / ajax call even 100kb gaan deserializen / serializen.
Gebruik gewoon een memory / file-based cache voor je grote dingen die zo min mogelijk overhead heeft.

Gooi alleen dingen in je session die user-specifiek zijn ( en vertalingen zijn dat niet ).

Een beetje handig opgezette cache pakt alleen de dingen die nodig zijn en niet alles zoals sessions

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Verwijderd schreef op zondag 23 augustus 2009 @ 13:38:
bedankt allemaal voor de tips.

Ik heb met firebug wat zitten te profileren:

De ajax aanroep duurde 1.20s gaf firebug aan.

Om te testen aan waaraan dit ligt heb ik een simpele asynchrone request gedaan naar een hele simpele php pagina waar enkel het volgende instaat:
code:
1
2
3
<?php
echo "test";
?>


deze echo wordt dan met een alert uitgeschreven...
Ook dit heb ik even met profilen bekeken en de aanroep duurde nog steeds 1.0sec

Het kan dus niet liggen aan mijn php-scripts want ook voor dit zeer simpele script duurde het 1sec vooralleer de volledige request afgehandeld was.

Mij lijken deze tijden toch niet echt normaal ofwel?
Roep de pagina eens normaal aan, wat is dan de tijd in firebug?
Want synchroon / asynchroon betekent aan de webserver kant niets. Dus als je deze pagina normaal aanroept zou het ook 1.0 sec moeten duren...

Acties:
  • 0 Henk 'm!

  • Manuel
  • Registratie: Maart 2008
  • Laatst online: 17-09 14:28
Verwijderd schreef op zondag 23 augustus 2009 @ 13:38:
bedankt allemaal voor de tips.

Ik heb met firebug wat zitten te profileren:

De ajax aanroep duurde 1.20s gaf firebug aan.

Om te testen aan waaraan dit ligt heb ik een simpele asynchrone request gedaan naar een hele simpele php pagina waar enkel het volgende instaat:
code:
1
2
3
<?php
echo "test";
?>


deze echo wordt dan met een alert uitgeschreven...
Ook dit heb ik even met profilen bekeken en de aanroep duurde nog steeds 1.0sec

Het kan dus niet liggen aan mijn php-scripts want ook voor dit zeer simpele script duurde het 1sec vooralleer de volledige request afgehandeld was.

Mij lijken deze tijden toch niet echt normaal ofwel?
Dit probleem herken ik, je draait toch niet toevallig IIS7?
PHP Windows Builds Je moet dan de VC9 hebben, indien je Apache draait, kies dan voor VC6 zoals het er staat uitgelegd. (Non-thread-safe dacht ik voor IIS)..

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Manuel schreef op zondag 23 augustus 2009 @ 13:54:
[...]


Dit probleem herken ik, je draait toch niet toevallig IIS7?
PHP Windows Builds Je moet dan de VC9 hebben, indien je Apache draait, kies dan voor VC6 zoals het er staat uitgelegd. (Non-thread-safe dacht ik voor IIS)..
Ik heb dus gwn xampp draaien op mijn test server, zal eens deze versie van php erop zetten

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
OK opgelost duurt nu 10ms :)

Bedankt!

Acties:
  • 0 Henk 'm!

  • Eddy Dean
  • Registratie: November 2007
  • Laatst online: 16-09 15:20
Nog even een snelle reactie op kipusoep en Gomez12:

Ik ben met jullie eens dat je grote dingen die niet user-specifiek zijn niet in een session hoort te zetten. De vertalingen horen er dus inderdaad niet, maar de taal/locale van de user (bijvoorbeeld en_US) wel.

Wat is er tegen een UserPreferences object als deze (mijn PHP is wat roestig, sorry)?
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    error_reporting(E_ALL);
    class UserPreferences
    {
        private $bgColor = "#abcdef";
        private $fontSize = "12pt";
        
        public function getBgColor() { return $this->bgColor; }
        public function setBgColor($color) { $this->bgColor = $color; }
        
        public function getFontSize() { return $this->fontSize; }
        public function setFontSize($size) { $this->fontSize = $size; }
        
        private function __construct() {}
        
        public static function getInstance()
        {
            if(session_id()==="") 
            {
                echo "Starting session<br>";
                session_start();
            }
            
            if(!isset($_SESSION['_UserPreferences']))
            {
                echo "Creating new UserPreferences object<br>";
                $_SESSION['_UserPreferences'] = new UserPreferences();
            }
            return $_SESSION['_UserPreferences'];
        }
    }
    
    $up = UserPreferences::getInstance();
    
    echo "Background color: " . $up->getBgColor() . "<br>";
    echo "Font size: " . $up->getFontSize() . "<br>";


Vinden jullie het beter om voor iedere pagina dit object opnieuw op te bouwen door een query te doen naar de database om daar de preferences uit te vissen, in plaats van het op deze manier op te slaan?

Om een idee te geven van de snelheid van het serializen en deserializen: Ik heb een class gemaakt die exact gelijk is aan bovenstaande, alleen heeft deze in totaal 1000 member variabelen die allemaal een string van 6 tekens bevatten ("koekje" om precies te zijn). Het uitvoeren van $up = UserPreferences::getInstance() duurt dan gemiddeld 8.5ms als het object al in de sessie staat.

Mijn mening blijft dus dat je best wel het een en ander in de session mag zetten, maar alleen als het bij kleine, user-specifieke dingen blijft.

Acties:
  • 0 Henk 'm!

  • plofkip
  • Registratie: Oktober 2002
  • Laatst online: 03-09 19:11
Eddy Dean schreef op zondag 23 augustus 2009 @ 15:02:
Nog even een snelle reactie op kipusoep en Gomez12:

Ik ben met jullie eens dat je grote dingen die niet user-specifiek zijn niet in een session hoort te zetten. De vertalingen horen er dus inderdaad niet, maar de taal/locale van de user (bijvoorbeeld en_US) wel.

Wat is er tegen een UserPreferences object als deze (mijn PHP is wat roestig, sorry)?
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    error_reporting(E_ALL);
    class UserPreferences
    {
        private $bgColor = "#abcdef";
        private $fontSize = "12pt";
        
        public function getBgColor() { return $this->bgColor; }
        public function setBgColor($color) { $this->bgColor = $color; }
        
        public function getFontSize() { return $this->fontSize; }
        public function setFontSize($size) { $this->fontSize = $size; }
        
        private function __construct() {}
        
        public static function getInstance()
        {
            if(session_id()==="") 
            {
                echo "Starting session<br>";
                session_start();
            }
            
            if(!isset($_SESSION['_UserPreferences']))
            {
                echo "Creating new UserPreferences object<br>";
                $_SESSION['_UserPreferences'] = new UserPreferences();
            }
            return $_SESSION['_UserPreferences'];
        }
    }
    
    $up = UserPreferences::getInstance();
    
    echo "Background color: " . $up->getBgColor() . "<br>";
    echo "Font size: " . $up->getFontSize() . "<br>";


Vinden jullie het beter om voor iedere pagina dit object opnieuw op te bouwen door een query te doen naar de database om daar de preferences uit te vissen, in plaats van het op deze manier op te slaan?

Om een idee te geven van de snelheid van het serializen en deserializen: Ik heb een class gemaakt die exact gelijk is aan bovenstaande, alleen heeft deze in totaal 1000 member variabelen die allemaal een string van 6 tekens bevatten ("koekje" om precies te zijn). Het uitvoeren van $up = UserPreferences::getInstance() duurt dan gemiddeld 8.5ms als het object al in de sessie staat.

Mijn mening blijft dus dat je best wel het een en ander in de session mag zetten, maar alleen als het bij kleine, user-specifieke dingen blijft.
Ik ben dat met je eens.
Alleen op mijn werk (gebruiken we ASP.NET) hebben we ervoor gekozen geen Session meer te gebruiken.
Als je inlogt krijg je nu een cookie met daarin een door ons gegenereerde SessionID. Aan de hand daarvan wordt voor elke aanroep de informatie uit de database opgehaald via WCF. Dit werkt heerlijk snel :)

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Eddy Dean schreef op zondag 23 augustus 2009 @ 15:02:
Nog even een snelle reactie op kipusoep en Gomez12:

Ik ben met jullie eens dat je grote dingen die niet user-specifiek zijn niet in een session hoort te zetten. De vertalingen horen er dus inderdaad niet, maar de taal/locale van de user (bijvoorbeeld en_US) wel.
...
Vinden jullie het beter om voor iedere pagina dit object opnieuw op te bouwen door een query te doen naar de database om daar de preferences uit te vissen, in plaats van het op deze manier op te slaan?

...
Mijn mening blijft dus dat je best wel het een en ander in de session mag zetten, maar alleen als het bij kleine, user-specifieke dingen blijft.
Idd, kleine user specifieke dingen zijn goed in een sessie te zetten afhankelijk van hoe vaak je het gebruikt...

Dingen als een bgcolor etc zou ik persoonlijk niet in een sessie zetten, maar gewoon lekker in de db laten omdat dit gewoon puur view dingen zijn en ik genoeg ajax-calls / header 302's gebruik die helemaal geen bgcolor nodig hebben.
Profieldingen laad ik liever niet bij elke pageload in het geheugen, maar gooi ik liever over het gigabit lijntje in het dc. En ik ga al helemaal niet beginnen aan sommige profieldingen in sessies gooien en andere uit dbase ophalen, maar zolang het klein genoeg is en je er zelf wijs uit wordt zie ik er geen bezwaar op tegen.

Mijn bezwaar was voornamelijk tegen het opslaan van dingen in sessions die lang duren / veel data produceren, dat zorgt gewoon voor ontiegelijk veel overhead en al helemaal als je ajax gaat gebruiken ( waardoor je al die leuke bgcolor's etc niet meer gebruikt maar wel inlaad ).
Even een enkel profiel + template instellingen voor een user ophalen mag voor een beetje geindexeerde dbase totaal geen tijd kosten...

Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 23:06
kipusoep schreef op zondag 23 augustus 2009 @ 15:53:
[...]

Ik ben dat met je eens.
Alleen op mijn werk (gebruiken we ASP.NET) hebben we ervoor gekozen geen Session meer te gebruiken.
Als je inlogt krijg je nu een cookie met daarin een door ons gegenereerde SessionID. Aan de hand daarvan wordt voor elke aanroep de informatie uit de database opgehaald via WCF. Dit werkt heerlijk snel :)
Dit is toch precies hetzelfde als je het door ASP.Net laat doen, met als stateprovider SQLServer?

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

kipusoep schreef op zondag 23 augustus 2009 @ 15:53:
Alleen op mijn werk (gebruiken we ASP.NET) hebben we ervoor gekozen geen Session meer te gebruiken.
Als je inlogt krijg je nu een cookie met daarin een door ons gegenereerde SessionID. Aan de hand daarvan wordt voor elke aanroep de informatie uit de database opgehaald via WCF. Dit werkt heerlijk snel :)
Waarom?

Jullie huidige implementatie lijkt me eerder langzamer dan de standaard implementatie waarbij ook een cookie gezet wordt, maar waarbij de sessiondata gewoon in het geheugen blijft. Als de overweging 'snelheid' is, vraag ik me uberhaupt af hoe jullie tot deze oplossing gekomen zijn. Bij mij gaat iig het NIH antipattern vlaggetje heel hard wapperen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • plofkip
  • Registratie: Oktober 2002
  • Laatst online: 03-09 19:11
Janoz schreef op maandag 24 augustus 2009 @ 13:33:
[...]

Waarom?

Jullie huidige implementatie lijkt me eerder langzamer dan de standaard implementatie waarbij ook een cookie gezet wordt, maar waarbij de sessiondata gewoon in het geheugen blijft. Als de overweging 'snelheid' is, vraag ik me uberhaupt af hoe jullie tot deze oplossing gekomen zijn. Bij mij gaat iig het NIH antipattern vlaggetje heel hard wapperen.
Gaat niet alleen om snelheid, maar ook om server-performance.
De sessie in ASP.NET wordt server-side opgeslagen, en aangezien we webapplicaties draaien waar veel bezoekers komen, is het niet prettig dat allemaal server-side op te slaan.
De worker processen kunnen dan nog weleens flink uitschieten wat betreft geheugen gebruik.

Nee, dan sla ik liever alleen een SessionID op en trek de info wel (wat zeeeer goed cachebaar is) van de WCF.

[ Voor 6% gewijzigd door plofkip op 24-08-2009 22:49 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

Ik ben niet zo bekend met .Net, maar wat moet ik me voorstellen bij 'de WCF'?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'

Pagina: 1