Synchronisez Votre Code JavaScript Avec Async-Mutex

Compteur De Serveur Commandé

L’exemple ci-dessus est un compteur de serveur ordonné que nous souhaitons construire. Lorsque vous cliquez sur le bouton:

  • Une requête asynchrone est envoyée à un serveur
  • Le serveur incrémente un compteur interne
  • Le serveur renvoie la valeur du compteur actuel
  • Le client (notre page Web) affiche le compteur dans un Toast illustré ci-dessus.

Il est important que l’ordre des nombres soit conservé à la réception. Alors, comment pouvons-nous synchroniser l’ordre des demandes? Nous savons que les requêtes réseau sont asynchrones. Il est tout à fait possible que la première demande prenne plus de temps à arriver que la deuxième demande, ou que la deuxième demande prenne plus de temps que la troisième demande, et ainsi de suite. Cette arrivée de demandes hors service sera un problème pour notre application.

L’approche « Sans synchronisation »

Que se passerait-il si nous devions développer cette application sans constructions de synchronisation? Voici un exemple d’implémentation d’une simulation de cette application sans synchronisation.

Le serveur est simulé avec processCommmand(), et les retards réseau sont simulés avec serverDelay(). Comme il n’y a pas de mécanismes de synchronisation, une fois le bouton « Cliquez sur moi » cliqué, une nouvelle demande est immédiatement déclenchée.

Ceci est le résultat de cette implémentation.

Euh oh – les numéros, comme prévu, apparaissent hors service, et nous n’avons pas réussi à faire notre demande pour afficher les numéros dans l’ordre.

Surmonter le problème de panne avec Mutex

Le problème est que les demandes réseau sont en panne, mais notre application veut qu’elles soient en ordre. Une façon de résoudre ce problème consiste à utiliser un verrou Mutex pour n’autoriser qu’une seule requête à être traitée à la fois, bloquant les autres requêtes jusqu’à ce que ce soit leur tour.

Voici l’implémentation avec Mutex.

Le flux d’utilisation de l’API Mutex est le suivant:

  • Ligne 23 : Une demande d’acquisition du clientLock est lancée. Cette requête bloquera si quelqu’un d’autre a déjà acquis le verrou et ne l’a pas encore libéré
  • Ligne 33 : Le verrou client est libéré après que le serveur a répondu et que nous avons montré le toast. Cela permet à d’autres événements de clic de bouton de concourir maintenant pour le verrou et d’initier leur demande de réseau de serveur!

Ce mécanisme de verrouillage garantit qu’un seul événement de bouton sera traité à la fois, bloquant et mettant en file d’attente les autres. Nous avons maintenant réalisé la mise en œuvre ordonnée prévue de notre exemple original montré au début!

Limitation du nombre de toasts visibles

Que se passe-t-il si vous n’aimez pas que plusieurs Toasts puissent inonder l’écran à la fois? Nous pouvons étendre notre logique pour limiter le nombre de toasts affichés à la fois. Notre construction de synchronisation ici serait un Sémaphore!

Pensez à un Sempahore comme un Mutex, mais il peut permettre à plusieurs requêtes asynchrones d’exécuter un morceau de code à la fois. Vous pouvez également configurer le nombre maximum!

En utilisant un Mutex et un Sémaphore, j’ai pu limiter le nombre de Toasts à l’écran à 2 à la fois.

Et voici le code associé à l’exemple ci-dessus

Ligne 6

La structure Sempahore est initialisée avec la valeur 2, qui spécifie que seul un maximum de 2 toasts peut être affiché à la fois.

Ligne 26-31

Notre logique sémaphore vient nous aider lorsque nous voulons afficher le Toast. Nous tentons d’acquérir le Sempahore. Si nous avons réussi, nous créons l’objet Toast, puis nous passons releaseSemaphore() à la fonction completeCallback du Toast. Ce rappel est appelé lorsque le toast est rejeté.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.