Toon posts:

[JSP/AJAX] Requests komen te snel

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Heb in javascript een for loopje waarmee ik dmv xmlhttprequest een stuk jsp script aanroep die vervolgens een xml genereert.

Nu is het alleen zo dat de ene bewerking in de jsp (die een database bewerking doet) afhankelijk is van de vorige bewerking. Dit omdat deze (opeenvolgende) acties gevolg hebben op 1 regel in de database, waarbij in de jsp een check wordt gedaan of de regel al bestaat. Zo nee, een insert, zo ja een update.

Nu is alleen het probleem dat het aanroepen van de jsp te snel op elkaar volgt, waardoor de ene jsp nog niet 'klaar' is als de andere al weer start. Dit resulteert dan in het feit dat er twee processen van de jsp parallel aan elkaar lopen en daardoor twee inserts plaatsvinden ipv eerst een insert en daarna een update.

Als ik echter een alert (=pauze moment) plaats in het for loopje dan gaat alles goed, omdat de jsp dan rustig de tijd heeft om zijn werk te doen.

Nu wil ik natuurlijk geen alert ertussen en heb ik het geprobeerd met een (eigen gemaakte) pauze functie, maar dit werkt ook niet echt.

Heeft iemand een idee wat ik hieraan kan doen of hoe ik kan detecteren of de jsp al klaar is met zijn werk??


PS: in firefox werkt het wel helemaal goed, maar dus niet in IE. Blijkbaar start ie al een volgend proces op, terwijl hij nog niet klaar is met de vorige.

PS2: nu heb ik wel een onreadystatechange() check erin, die pas wat uitvoert als die 4 is, maar blijkbaar gaat hij toch al verder in de for-loop

[ Voor 7% gewijzigd door Verwijderd op 24-01-2007 13:22 ]


Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 19:09

chem

Reist de wereld rond

Je probleem moet je niet zoeken aan de ajax-kant, maar aan de jsp-kant. Denk aan locking, race-conditions en dergelijke om te zoeken :)

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Plaats rond je JSP code een synchronized block, zodat je aan de server zijde maar 1 request gelijkertijd afhandelt
Java:
1
2
3
synchronized(this) {
 // logica
}

edit:
quote removed

[ Voor 91% gewijzigd door -FoX- op 24-01-2007 14:05 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
hmm.. dat werkt niet echt.. maar zou dat hiermee te maken kunnen hebben??
Remember that synchronization locks objects, not methods or code. Simply because a method, or section of code, is declared synchronized does not necessarily mean it is executed by only one thread at a time. This is important if the code in the synchronized method or block alters a mutually shared resource.
Bron: http://www-128.ibm.com/de...ibrary/j-praxis/pr46.html

Wat ik me afvraag is of er niet meer gedaan kan wordwen met readystate, maar ik weet dus nu zo even niet wat..

Acties:
  • 0 Henk 'm!

  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 16:29
Binnenkomende requests demultiplexen en in een queue gooien en dan één worker thread die queue laten uitlezen en de requests laten verwerken?

Acties:
  • 0 Henk 'm!

  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Misschien heb je hier iets aan.
http://www.javaworld.com/...12-threadsafe.html?page=5

Ik vond het sowieso wel een goed artikel. Staan een paar goede oplossingen in.

Pas wel op met die SingleThreadModel, dat is niet goed voor performance, want alle requests worden dan sequentieel afgehandeld...

Fat Pizza's pizza, they are big and they are cheezy


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
het probleem is dat ik een soort framework werk waar ik dus niet echt toegang heb tot de threads enzo.
ik kan me dus enkel beperken tot het gebruik van scripts, die vervolgens diior het systeem/gramework worden gecompiled. Ik zit dus neit echt op systeem niveau te werken.

Daarom probeer ik te kijken naar oplossingen om het toch aan de javascript kant op te lossen. En aangezien de test met de alert goed werkte probeer ik dus alternatief hiervoor te vinden.

Acties:
  • 0 Henk 'm!

  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 16:50

Crazy D

I think we should take a look.

Hmm ajax niet asynchroom maar synchroom de calls laten doen naar de server? Dan gaat ie pas verder met de 2e als de 1e afgerond is.

Exact expert nodig?


Acties:
  • 0 Henk 'm!

  • chime
  • Registratie: Januari 2005
  • Laatst online: 09-09 12:46
Kan je in je javascript de functie niet gewoon terug opnieuw aanroepen nadat je server je eerste request heeft verwerkt:

code:

deXMLHttpRequest.onreadystatechange = functie;

function functie(){
if (deXMLHttpRequest.readyState == 4) {
if (deXMLHttpRequest.status == 200) {
..code..
deXMLHttpRequest.onreadystatechange = functie;
deXMLHttpRequest.send(null);
}
}
}

Met het plaatsen van extra condities kan je vervolgens de functie niet meer uitvoeren en de requests dus stoppen.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 23:37

Janoz

Moderator Devschuur®

!litemod

Alle javascript oplossingen die de ajax request beter 'timen' zijn zinlose oplossingen. Je hebt het probleem dan misschien opgelost voor 1 client, maar race problemen zullen keurig weer de kop opsteken zodra er twee mensen tegelijk je pagina bezoeken. Je zult je JSP gewoon robuust genoeg moeten maken.

Het synchronised block zou moeten werken zolang alle aanroepen maar dezelfde mutex gebruiken. Ik heb geen idee hoe jullie het verder in elkaar hebben zitten (en ik vind het erg vreemd dat er blijkbaar dit soort fundamentele fouten in de implementatie zitten) maar het zou kunnen dat er meerdere instanties van die servlet zijn (waarnaar de jsp gecompileerd is). Je applicatie server neemt dan misschien een andere instantie waardoor niet hetzelfde object als mutex gebruikt wordt.

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!

  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Ik lees je startpost nog eens door en zit me af te vragen waarom je de DB code in je servlet hebt staan. Kun je het niet met EJB of misschien Spring regelen en alles in een transactie draaien? Isolation level van je database goed zetten en dan ben je volgens mij al een hele stap verder. Javascript/Web oplossingen is alleen maar symptoombestrijding ben ik bang.

Fat Pizza's pizza, they are big and they are cheezy


Acties:
  • 0 Henk 'm!

Verwijderd

JKVA schreef op woensdag 24 januari 2007 @ 20:40:
Ik lees je startpost nog eens door en zit me af te vragen waarom je de DB code in je servlet hebt staan. Kun je het niet met EJB of misschien Spring regelen en alles in een transactie draaien? Isolation level van je database goed zetten en dan ben je volgens mij al een hele stap verder. Javascript/Web oplossingen is alleen maar symptoombestrijding ben ik bang.
Ik lees je reactie nog eens door en ik vraag me af waarom je op een 'driewieler vraag' een 'raketwetenschap antwoord' geeft...

Het eerder, door -FoX-, voorgestelde synchronized(this){} om de database calls heen lijkt me dus meer dan voldoende voor TS.

Acties:
  • 0 Henk 'm!

  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Ik weet niet of het een driewieler vraag is. Concurrency en multithreaden vind ik over het algemeen geen driewieleronderwerpen.

Bovendien is een synchronized block in een instance method van toepassing op de instantie, dus als de container besluit om voor de tweede request een andere servletinstantie te gebruiken kun je al in de problemen zitten, want dan heb je niks aan je synchronized. Je kan er redelijk van uitgaan dat er maar één instantie is bedenk ik me...

Je moet je bewust zijn van het feit dat de container vanalles kan beslissen.

In een transactie draaien is dus stukken robuuster.

Dus ik denk niet dat het raketwetenschap is. Bovendien pretendeer ik niet te weten wat de voorkennis is van de TS dus de opmerking kan allicht nut hebben...

[ Voor 5% gewijzigd door JKVA op 25-01-2007 08:36 ]

Fat Pizza's pizza, they are big and they are cheezy


Acties:
  • 0 Henk 'm!

Verwijderd

JKVA schreef op woensdag 24 januari 2007 @ 21:45:
Ik weet niet of het een driewieler vraag is. Concurrency en multithreaden vind ik over het algemeen geen driewieleronderwerpen.
Doe je nu alsof je niet begrijpt wat ik bedoel ofzo? :/
JKVA schreef op woensdag 24 januari 2007 @ 21:45:
Bovendien is een synchronized block in een instance method van toepassing op de instantie, dus als de container besluit om voor de tweede request een andere servletinstantie te gebruiken kun je al in de problemen zitten, want dan heb je niks aan je synchronized.
We hebben het over JSP; een tweede instantie vind doorgaans pas plaats bij:
code:
1
<%@ page isThreadSafe="false" %>

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Overigens is het wel degelijk good practice om je clientside ajax-applicatie ook niet onnodige requests te laten doen. Denk bijvoorbeeld aan een suggest-like applicatie met een ajax-call die geiniteerd wordt bij elke keystroke en een snelle typist:

Gebruiker typed een 'a' -> ajax-call wordt gemaakt met verzoek aan de server om matches beginnend met een 'a' terug te sturen.
Nog voordat de server een respons heeft kunnen genereren die door de client verwerkt kan worden heeft onze gebruiker ook al een 'j' en nog een 'a' getyped, dus ondertussen zijn er alweer 2 nieuwe requests gedaan naar de server: eentje met een verzoek voor matches beginnend met 'aj' en nog eentje met een verzoek voor matches beginnend met 'aja'.

Beter zou zijn geweest als de ajax-applicatie had gewacht totdat het eerste request verwerkt was en daarna meteen de request had gedaan voor 'aja' (dus de request voor 'aj' helemaal niet genereren). Dat scheelt zowel serverside als clientside enorm in je performance.

Sowieso verdient het aanbeveling om het aantal simultane ajax-requests te limiteren (veel browsers hebben standaard overigens al een limiet van 2 simultane requests naar 1 server). Met asynchrone communicatie betekend dat dus dat je in javascript met een soort van queue zal moeten gaan werken.

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 19:56

MueR

Admin Tweakers Discord

is niet lief

Of je hiermee geholpen bent weet ik niet, maar toch. Wat ik zelf in ieder geval doe hiermee, is alle ajax requests opslaan in een cache. Nadat een request is uitgevoerd, wordt er een halve seconde gewacht, voordat de volgende request uit de cache wordt gehaald en uitgevoerd. Ik pas dit toe op form validation, aangezien het toch een heel snelle typist is die twee velden binnen een paar tienden van seconden kan invullen.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
laat ik jullie dan maar uit de brand helpen. Het was ionderdaad een driewielervraag en van de server kant heb ik (helaas) nog niet zo veel kaas gegeten, dus het gaat mij boven de pet nu om me bezsig te houden met threading, race conditions e.d.

Het synchronized block kan ik, voor zover ik begrijp, sowieso om mijn jsp code heenzetten, dus dat zal ik ook doen, al leek het niet te werken. maar baart het niet, dan schaadt het niet (??)

De optie van Muer had ik al geprobeerd, en al is niet mijn favoriete oplossing, het leek sowieso niet goed te werken :-) Vaak deed hij het wel, maar soms ook niet, en dat is m.i. dus te instabiel.

De optie van Crisp spreekt me dus het meest aan :)

Zelf had ik dit al geprobeerd, maar dat wil op 1 of andere manier niet werken, alhoewel het idee me juist lijkt..
JavaScript:
1
2
3
4
5
6
7
8
while(true) {
    if(xmlhttp == null || (!xmlhttp != null && xmlhttp.readyState == 4)) {
        // proces unlocked
        break;
    }

        // rest van xmlrequest handelingen
}


Zit ik zo op de goede weg?

Een andere optie die ik zou kunnen gebruiken, maar ook niet echt mijn voorkeur heeft, omdat het 'ranzig' is, is deze:

In een variabele houdt ik bij hoe vaak hij een serverrequest moet doen en aan het eind van de functie die de request aanroept als hij klaar is (xmlhttp.onreadystatechange = xmlHandler) zet ik een if-lusje die dezelfde functie weer aanroept. Dit gebeurt dus net zo vaak totdat het aantal in de variabele bereikt is. Zo zullen dus de xml requests netjes 1 voor 1 uitgevoerd worden en dus geen fouten meer voorkomen..

Wat lijkt jullie de beste (client side) oplossing?

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Dan kan je beter gebruik gaan maken van synchrone requests want op deze manier 'lock' je de hele browser...

Overigens mis ik een beetje de informatie van wat voor requests je uitvoert en hoe en hoe vaak die getriggered worden. De afgelopen 2 dagen ben ik al meer posts tegengekomen hier en in WEB van mensen die op elke keypress een request af gaan vuren en daarmee in de problemen komen...
Het is toch niet zo moeilijk te begrijpen dat als een applicatie in luttele seconden tientallen requests gaat genereren dat er dan gewoon iets mis is met je applicatie?

[ Voor 49% gewijzigd door crisp op 25-01-2007 09:45 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Verwijderd schreef op woensdag 24 januari 2007 @ 22:09:
[...]
Doe je nu alsof je niet begrijpt wat ik bedoel ofzo? :/


[...]

We hebben het over JSP; een tweede instantie vind doorgaans pas plaats bij:
code:
1
<%@ page isThreadSafe="false" %>
Je hebt gelijk, ik zat zelf gisteren ook nog ff na te dubben over mijn post en ik bedacht me toen ook dat er normaal gesproken gewoon 1 instantie gebruikt wordt. Weliswaar wel multithreaded.

Maakt het nog steeds slim om niet uit te gaan van deze mazen in de spec, maar gewoon zelf via een singleton of weet ik wat te werken.

Dus de opmerking was idd wat over the top. :P

Fat Pizza's pizza, they are big and they are cheezy


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ok.. ik maak nu gebruik van synchronous requests en dat werkt perfect! Misschien is het niet de beste oplossing, maar voor nu werkt het iig goed..

Bedankt voor de hulp!
Pagina: 1