2 Ajax calls naar dezelfde server, tegelijkertijd

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Erwin H

Erwin H

05/12/2013 10:28:15
Quote Anchor link
De situatie is dat ik een database bewerking moet doen die nogal lang duurt (letterlijk minuten). De bewerking start ik via een ajax call, waar ik verder niet op het resultaat wacht. Tegelijkertijd start ik een loop om elke zoveel seconde de voortgang te controleren en die ook op het scherm te laten zien aan de gebruiker.

Bij mijn weten is ajax asynchroon en zou je dus gewoon een volgende call moeten kunnen starten als de vorige nog niet compleet is. Op een andere pagina maak ik bijvoorbeeld 8 calls tegelijk, waarbij het duidelijk is dat die ook tegelijkertijd worden afgehandeld door de server (niet in mijn testomgeving lokaal overigens, maar wel op mijn VPS).

In dit geval werkt het echter niet. De check call krijgt pas een resultaat terug van de server als de eerste call helemaal is afgehandeld door de server. Met andere woorden, ik zie nog steeds geen progressie in het verloop. Mijn vraag is nu dus, waarom niet? Kan het door de database komen die door de vele inserts helemaal gelocked is? Mijn tabellen zijn InnoDB en dus zou er rowlocking moeten zijn, niet de gehele tabel.
 
PHP hulp

PHP hulp

01/05/2024 17:17:11
 
Ward van der Put
Moderator

Ward van der Put

05/12/2013 10:58:49
Quote Anchor link
Het kan gewoon asynchroon, maar daardoor kunnen de calls in een verkeerde volgorde binnenkomen of worden gestart. Usual suspects: de tragere start van het zwaardere PHP-script of een client die maar twee concurrent connections gebruikt (waarvan er een dan bijvoorbeeld nog iets anders moet binnenhalen).

Ik heb iets vergelijkbaars ooit opgelost door de tweede call pas te starten op een HTTP/1.1 204 No Content respons van de eerste.
 
Erwin H

Erwin H

05/12/2013 11:09:50
Quote Anchor link
Of ze in de verkeerde volgorde binnenkomen maakt niet uit. De eerste start een actie, terwijl de tweede call (in een loop) gewoon de progressie checkt. Als bij de eerste call de start nog niet is gebeurd, dan komt er bij die call gewoon 0 terug, wat verder geen probleem is.

Ik begrijp alleen je opmerking niet over die No Content response. Volgens mij kan die response pas komen zodra de eerste call helemaal is afgelopen, maar dat wil ik dus niet, want dat kan minuten duren. Of kan je de header al versturen voor het hele script is uitgevoerd? En daarmee bedoel ik dat die header dus ook echt direct bij de browser terecht komt en niet pas aan het einde?

Overigens kwam ik via stackoverflow op een andere mogelijke oorzaak waarom het niet werkt. De eerste call opent een session en de tweede kan die pas openen als de eerste session afgesloten is. Een eerste test wees me net uit dat dat inderdaad het probleem zou kunnen zijn. Nu zien hoe ik dat op kan lossen....
 
Kris Peeters

Kris Peeters

05/12/2013 11:18:52
Quote Anchor link
Is er geen mogelijkheid dat je die lange bewerking kan verdelen over verschillende calls?

Ik zeg maar wat... 1000 rijen per keer.
Met Ajax houd je een teller bij, die telkens wordt verhoogd.

Dat zou ook je progress bar veel accurater maken
 
Ward van der Put
Moderator

Ward van der Put

05/12/2013 11:21:21
Quote Anchor link
Ja, je kunt de 204 header echoën plus flushen en daarna de database aan het werk zetten. De client verwacht dan ook geen content meer uit de eerste call. Die 204-respons gebruiken voor de tweede call is aansluitend op zich wel logisch, aangezien je een gestart proces gaat meten. De opzet is eigenlijk synchroon.
 
Erwin H

Erwin H

05/12/2013 11:23:25
Quote Anchor link
Wat mij betreft niet, omdat ik een csv bestand inlees, dat ik vervolgens lijn voor lijn verwerk. Als ik het dus stap voor stap doe, moet ik elke keer eerst dat hele csv bestand door voor ik kan inlezen. Op zich wel mogelijk, maar ik zie niet het voordeel ten opzichte van alles in 1 keer doen (behalve dan als het 1 wel werkt het ander niet natuurlijk).
 
Kris Peeters

Kris Peeters

05/12/2013 11:24:55
Quote Anchor link
Ik vreesde al zo iets
 
Erwin H

Erwin H

05/12/2013 11:25:35
Quote Anchor link
Ward van der Put op 05/12/2013 11:21:21:
Ja, je kunt de 204 header echoën plus flushen en daarna de database aan het werk zetten. De client verwacht dan ook geen content meer uit de eerste call. Die 204-respons gebruiken voor de tweede call is aansluitend op zich wel logisch, aangezien je een gestart proces gaat meten. De opzet is eigenlijk synchroon.

Ga ik eens proberen. Wat ik eerder zei over dat het niet uitmaakt klopt nog wel, maar je hebt wel gelijk dat het proces technisch gezien niet klopt dat je een progressie checkt als er nog niets gestart is.

Hoe flush je die header? Of gaat dat automatisch als de header weggeschreven wordt?
 
Ward van der Put
Moderator

Ward van der Put

05/12/2013 11:27:03
Quote Anchor link
Hoe meet je de voortgang?
 
Erwin H

Erwin H

05/12/2013 11:31:49
Quote Anchor link
De voortgang is via een check op de database.
 
Ward van der Put
Moderator

Ward van der Put

05/12/2013 11:37:22
Quote Anchor link
Als je daarvoor de sessie niet nodig hebt, zou ik die fijn achterwege laten.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
header('HTTP/1.1 204 No Content');
flush();
// En dan de rest...
?>
 
Erwin H

Erwin H

05/12/2013 11:44:22
Quote Anchor link
Probleem is inderdaad opgelost door de sessie te sluiten. Op zich heb ik die wel nodig, want ik moet weten welke gebruiker is ingelogd, maar door de sessie direct te sluiten aan het begin van de call die de inlees actie start (via session_write_close) kan de andere call gewoon afgehandeld worden. Die loop loopt nu dus en de progressie wordt getoond op het scherm zoals ik wil.

Nu alleen nog even die header erbij implementeren.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.