[Ajax] Clientside synced houden zonder feedback van backend*

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Garma
  • Registratie: Januari 2006
  • Laatst online: 26-01-2020
Hallo,

Ik heb een probleem en voor ik zelf ga lopen puzzelen, zou ik graag weten of iemand anders hier al eens heel hard over nagedacht heeft (in de vorm van een standaard model) wat ikz ou kunnen gebruiken

Het is als volgt. Ik heb een asynchrone web applicatie (ajax dus). Het gaat om een applicatie die elementen toevoegd aan een tabel, en deze elementjes kunnen bewerkt worden (naampjes, datum etc). Vloeiende usability is een belangrijke requirement, dus ik wil graag echt asynchroon ajax gebruiken. Dat wil zeggen dat het meeste werk in javascript gebeurd, en dat ik alleen de wijziging aan de database naar de server stuur, en verder dat de gebruiker niet op de ajax-call hoeft te wachten maar direct door kan met werken.

Nu mijn probleem. Als er een nieuw element aangemaakt wordt, weet ik nog niet de ID van het element in de database. Stel dat de gebruiker dit nieuwe element edit. Als de edit klaar is, wordt de edit naar de server gestuurd. Maar hoe weet de server nu om welk element het gaat, dus welk element ge-updated moet worden?

Oplossingen tot nu toe:
1. ik kan de nieuwe ID terugsturen naar de client en het element updaten. Nadeel: Niet volledig asynchroon (lees: als een edit klaar is voordat de call terug is heb je hetzelfde probleem) Dit is een reel probleem omdat sommige edits binnen een fractie van een seconde uitgevoerd kunnen worden

2. Ik kan de volgende ID in de database raden (da's nogal tricky overigens) en die meegeven als de applicatie gerenderd wordt. Dit gaat goed totdat de applicatie in meerdere windows geopend wordt.

ik hoop dat het een beetje duidelijk is.

[ Voor 6% gewijzigd door Garma op 15-10-2009 23:16 ]


Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Je gaat in een situatie komen dat je een soort van QueueManager gaat bijhouden. Sommige acties kan je direct uitvoeren andere zaken pas als de rest van de queue leeg is... Dat betekent dus idd dat je sommige acties niet kan uitvoeren en bewust vertraging moet inbouwen...

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
ID's gaan raden is natuurlijk nooit een goed idee :D Gewoon die vertraging inbouwen, requests gaan toch supersnel (mits je server niet in china staat natuurlijk) dus echt veel ga je er niet van merken.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Quick'n'Dirty: Ken er gewoon een tijdelijk ID aan toe, clientside. Verstuur die mee naar de server en laat de server met het nieuwe "auto increment ID" ook het tijdelijke ID terugsturen. Vervolgens pak je het element met het tijdelijke id en zet je 't 'final' id.

Dus: je hebt 3 regels op je scherm:

1 jan
2 jaap
3 piet

User maakt een nieuw record:

1 jan
2 jaap
3 piet
t1 rob

Browser verstuurt t1, rob naar de server. Server slaat record op; het nieuwe ID blijkt 5 te zijn geworden volgens de DB (iemand anders heeft misschien al 4 gemaakt). Server stuurt terug: t1, 5. Je werkt je gegevens bij:

1 jan
2 jaap
3 piet
5 rob

Records waar (nog) een tijdelijk ID aan hangt kun je niet wijzigen tot er een final ID aan hangt. Wel kan men ondertussen doorgaan met meer nieuwe records maken. Zodra een final ID is toegekend kan men die records uiteraard ook bewerken.

edit:

Hier stond onzin

[ Voor 44% gewijzigd door RobIII op 15-10-2009 23:50 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 21:51

Patriot

Fulltime #whatpulsert

RobIII schreef op donderdag 15 oktober 2009 @ 23:41:
[...]

Doorgaans gaan de requests misschien snel, maar als het 1 keer hikt (om welke reden dan ook) heb je een probleem. Ik zou hier dan ook écht nooooooit op vertrouwen of er maar van uit gaan dat 't wel goed komt :X
Dat doet Cartman toch ook niet? Hij geeft alleen aan dat wachten tot de request compleet is niet zo'n probleem is omdat de request waarschijnlijk snel is verwerkt. In het geval van zo'n hik is het enige 'probleem' dat de gebruiker even moet wachten (wat natuurlijk zo gek nog niet is).

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Ja, ik las het schijnbaar verkeerd. 'T is al laat :X My bad.

[ Voor 7% gewijzigd door RobIII op 15-10-2009 23:49 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Garma
  • Registratie: Januari 2006
  • Laatst online: 26-01-2020
hoi,

thanks allemaal!

@allemaal: meestal zal het wel goed gaan met die snelheid inderdaad, maar het is bepaald geen intranet applicatie die ik bouw. het moet ook in de VS (of china :) )bruikbaar zijn. Een seconde vertraging is te langzaam.

@Roblll: Jouw methode heeft hetzelfde effect als mijn 'raad-de-id' methode. wat gebeurd er als je 2 windows opent? de tijdelijke id gaat hetzelfde zijn. Als je dan in beide windows een element maakt, gaat de id van die 2 elementen aan de server side hetzelfde zijn. Je kan tricky dingen doen met timestamps ofzo... maar het probleem blijft dat de call niet asynchroon is en dus voor problemen kan zorgen

@Cartman: de ID raden heeft tot gevolg dat *als* het fout gaat (dus 2 asynchrone calls binnen een kwart seconde mbt hetzelfde element) dat het dan soort van per ongeluk goed gaat.. kansberekening zeg maar :)

@BtM909: thanks... ik hoopte dat dat niet nodig zou zijn maar het lijkt er op dat ik wel zal moeten

[ Voor 21% gewijzigd door Garma op 16-10-2009 00:14 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Garma schreef op vrijdag 16 oktober 2009 @ 00:10:
@Roblll: Jouw methode heeft hetzelfde effect als mijn 'raad-de-id' methode. wat gebeurd er als je 2 windows opent? de tijdelijke id gaat hetzelfde zijn. Als je dan in beide windows een element maakt, gaat de id van die 2 elementen aan de server side hetzelfde zijn. Je kan tricky dingen doen met timestamps ofzo... maar het probleem blijft dat de call niet asynchroon is en dus voor problemen kan zorgen
Je moet de t1 ook niet letterlijk nemen. Genereer gewoon lang een random cijfer oid. "t1" was voor de duidelijkheid/simpelheid :P Ik had ook "4523c698-b0e5-46be-b61a-855319707f6a" kunnen gebruiken ;)

Eventueel zou je als "tijdelijk ID" de MD5/SHA1/whatever hash van de data regel kunnen gebruiken, maar dat is weer gevaarlijk als je 2 dezelfde regels toe kunt/mag voegen. In dat geval zou je bijvoorbeeld hash(alle_velden + regelnummer) als temp-id kunnen gebruiken.

[ Voor 16% gewijzigd door RobIII op 16-10-2009 01:04 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Mijn €0,02:

Alle logica clientside afhandelen en de server alleen als data access layer laten functioneren, creëert een veiligheidslek van jewelste. Zeker wanneer je applicatie public-facing is. Javascript is per definitie niet veilig. Daarnaast staat er een webservice open waarvan de URL zo op te halen valt en waar jan en alleman je-wilt-niet-weten-wat naar toe kunnen sturen.

Wil je zorgen dat niemand met je applicatie gaat klooien, dan zul je invoer (ook) moeten valideren op de server. Daar ontkom je gewoonweg niet aan.


Wat betreft IDs voor nieuwe entiteiten:

Als je een degelijke data access layer hebt, kun je natuurlijk tijdelijke data transfer objecten in een session o.i.d. bijhouden. Je kunt je DTOs een speciale vlag 'IsNew' meegeven, waarna de ID property niet op een database property gaat slaan, maar op een incremented ID in dat tijdelijke opslag mechanisme. Je hebt hiervoor geen enkele hack nodig. Daarnaast kun je zo'n tijdelijke opslag aanmaken per gebruikerssessie en is de kans dat je zonder IDs komt te zitten dus erg klein. (zelfs met maar een 32bit integer).

Acties:
  • 0 Henk 'm!

  • Japius
  • Registratie: April 2003
  • Laatst online: 30-08 20:57
Garma schreef op vrijdag 16 oktober 2009 @ 00:10:
@Roblll: Jouw methode heeft hetzelfde effect als mijn 'raad-de-id' methode. wat gebeurd er als je 2 windows opent? de tijdelijke id gaat hetzelfde zijn.
De tijdelijke ID's lijken me clientside. Oftwel: al zijn er 100 clients met elk een element t1, _dat_ wordt nergens opgeslagen. Alleen de final id's moeten uniek zijn, en dat handel je dan ook op 1 plek af.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Ik vind het idee van RobIII vrij elegant als je perse geen vertraging wil hebben. Je blijft echter kans op collissions houden natuurlijk, hoewel die kans _erg_ klein is bij bijv. SHA256.

Acties:
  • 0 Henk 'm!

  • Garma
  • Registratie: Januari 2006
  • Laatst online: 26-01-2020
R4gnax schreef op vrijdag 16 oktober 2009 @ 10:57:

Wil je zorgen dat niemand met je applicatie gaat klooien, dan zul je invoer (ook) moeten valideren op de server. Daar ontkom je gewoonweg niet aan.
Uiteraard, daar had ik al op gerekend. Opzich kan het me niet schelen dat men aan de javascript gaat rotzooien, als uiteindelijk wat de database in gaat maar correct is. Gelukkig bied .net heel wat handige hulpmiddelen om dit te garanderen.

Anyway, ik denk dat ik inderdaad voor Roblll's methode ga. Jammer wel dat je dan dus bepaalde acties niet kan doen totdat de call terug is. Als iemand daar nog een oplossing voor weet...? (Je zou bv de clientside id serverside kunnen opslaan oid)

Acties:
  • 0 Henk 'm!

  • Garma
  • Registratie: Januari 2006
  • Laatst online: 26-01-2020
ok ik heb inderdaad voor Roblll's methode gekozen. Het probleem dat je als de call nog niet terug is geen wijzigingen kunt doen, heb ik opgelost door de call te delayen voor een halve seconde met behulp van setTimeOut(). Dus:

function f(){
if(id = tmpid) setTimeOut(f,500);

else SendAjaxCall
}

ik zie opzich geen mogelijkheden dat dit fout kan gaan...

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Als je toch een timeout gebruikt, kun je dan toch niet beter synchrone requests doen, of snap ik even niet waar die timeout voor is? :)

Acties:
  • 0 Henk 'm!

  • Garma
  • Registratie: Januari 2006
  • Laatst online: 26-01-2020
Cartman! schreef op zondag 25 oktober 2009 @ 09:40:
Als je toch een timeout gebruikt, kun je dan toch niet beter synchrone requests doen, of snap ik even niet waar die timeout voor is? :)
ja maar een strict synchrone request laat de gebruiker wachten en dat is een absolute no-no :)
Als de request naar de server moet en terug kan dat best wel irritant zijn als je in de VS zit en de server hier staat. Met die setTimeOut creer ik een soort impliciete queue .

Acties:
  • 0 Henk 'm!

  • ronn0
  • Registratie: Oktober 2009
  • Laatst online: 25-05 20:43
Het is misschien niet de meest nette oplossing, maar je zou ook i.p.v. een ID een hash kunnen gebruiken welke 100% uniek is.

Bijvoorbeeld een hash van IP + Timestamp + random cijfer tussen de 10000 en de 99999.
Pagina: 1