2 Ajax calls naar dezelfde server, tegelijkertijd
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.
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.
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.
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.
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....
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....
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
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
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.
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).
Ik vreesde al zo iets
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?
Hoe meet je de voortgang?
De voortgang is via een check op de database.
Als je daarvoor de sessie niet nodig hebt, zou ik die fijn achterwege laten.
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.
Nu alleen nog even die header erbij implementeren.




