2010-12-04 24 views
3

Quel est le meilleur moyen de traiter les requêtes Ajax hors séquence (de préférence en utilisant un jQuery)? Par exemple, une requête Ajax est envoyée depuis le navigateur de l'utilisateur chaque fois qu'un champ change. Un utilisateur peut changer dog_name en "Fluffy", mais un instant plus tard, elle le change en "Spot". La première demande est retardée pour une raison quelconque, donc elle arrive au serveur après la seconde, et son chien finit par être appelé "Fluffy" au lieu de "Spot".Comment gérer les requêtes Ajax hors séquence?

Je pourrais transmettre un horodatage côté client avec chaque requête et demander au serveur de le suivre dans le cadre de chaque enregistrement Dog et ignorer les demandes précédentes pour changer le même champ (mais seulement s'il y a une différence de moins de 5 minutes, au cas où l'utilisateur changerait l'heure sur sa machine).

Cette approche est-elle suffisamment robuste ou existe-t-il une meilleure approche plus standardisée?

EDIT:

Matt a fait un excellent point dans son commentaire. Il est préférable de sérialiser les demandes de modification du même champ. Existe-t-il une manière standard d'implémenter les files d'attente de requêtes Ajax?

EDIT # 2

En réponse au commentaire de @ cherouvim, je ne pense pas que je devrais verrouiller la forme. Le champ change pour refléter le changement de l'utilisateur, une demande de changement est placée dans la file d'attente. Si une demande de modification du même champ attend dans la file d'attente, supprimez cette ancienne requête. 2 choses que je devrais encore aborder:

  1. Placer une requête dans la file d'attente est une tâche asynchrone. Je pourrais avoir le gestionnaire de rappel de la demande précédente Ajax envoyer la prochaine demande dans la file d'attente. Le code Javascript n'est pas multithread (ou ... est-il?)

  2. Si une requête échoue, j'aurais besoin de l'interface utilisateur pour refléter l'état de la dernière requête réussie. Ainsi, si l'utilisateur change le nom du chien en "Spot" et que la requête Ajax échoue, le champ devra être redéfini sur "Fluffy" (la dernière valeur validée).

De quoi ai-je besoin?

+0

Plus simple: ne pas autoriser plusieurs demandes simultanées pour le même champ. Mettez-les en file d'attente si les changements se produisent rapidement. –

+0

@Matt Ball: et comment "verrouiller" toute la conversation display-form-push-changes du client? Ce n'est pas un seul cycle de demande/réponse, mais deux. – cherouvim

Répondre

3

Tout d'abord, vous devez sérialiser le traitement côté serveur pour chaque client. Si vous programmez en Java, la synchronisation de l'exécution sur l'objet de session http est suffisante. La sérialisation aidera au cas où la deuxième mise à jour viendrait alors que la première est en cours de traitement.

Une seconde amélioration que vous pouvez implémenter dans la mise à jour de votre entité est http://en.wikipedia.org/wiki/Optimistic_concurrency_control. Vous ajoutez une propriété version (et une colonne) pour votre entité. Chaque fois qu'une mise à jour se produit, elle est incrémentée une fois. En fait, la déclaration de mise à jour ressemble à:

update ... set version=6 ... where id=? and version=5; 

Si lignes affectées par la requête ci-dessus sont pseudoquery 0 alors quelqu'un d'autre a réussi à mettre à jour l'entité première. Ce que vous faites ensuite dépend de vous. Notez que vous devez rendre la version sur le formulaire de mise à jour html de l'entité en tant que paramètre caché et la renvoyer au serveur chaque fois que vous mettez à jour. Au retour, vous devez réécrire la version mise à jour.

Généralement, la première amélioration serait suffisante. Le second améliorera le système au cas où de nombreuses personnes éditeraient les mêmes entités en même temps. Il résout le problème de "mise à jour perdue".

+0

Le contrôle de version est un bon point, mais dans ce cas, je ne suis pas inquiet à propos des utilisateurs qui claquent mutuellement leurs mises à jour avec des données périmées. Dans mon cas, une série de petites mises à jour proviennent du même utilisateur en succession rapide. –

+0

Le contrôle de version s'applique à chaque mise à jour, même à partir du même utilisateur. Chaque mise à jour de champ Ajax est un incrément de version. Ainsi, votre changement "spot" incrémentera la version de 5 à 6 et votre "fluffy" sera détecté comme une mise à jour périmée (car il enverra également une version 5) et vous pourrez faire ce que vous voulez, par exemple ignorez-le. – cherouvim

1

Je voudrais implémenter une file d'attente du côté client avec le chaînage des demandes réussies ou des annulations sur les demandes infructueuses.

Vous devez définir "échoué", que ce soit un délai d'expiration ou une valeur renvoyée.