Vous galérez avec les problématiques HTTP ou asynchrones dans vos projets ?
Dans cette vidéo, on s'attaque à l'enfer des "race conditions" souvent rencontré avec du code asynchrone.
En 10 lignes de code...
Vous verrez comment résoudre définitivement un problème de code asynchrone en entreprise : événements utilisateurs, pulling toutes les 15 secondes et requêtes HTTP...
Un cas concret, une solution simple, et des astuces pratiques pour éviter les erreurs courantes.
Bon visionnage, Simon.
00:00 : Introduction 00:08 : Étude de cas d'un problème asynchrone en entreprise 00:48 : La problématique infernale des "race conditions" 02:13 : Quand 1 seul opérateur RxJS ne suffit pas 03:35 : La solution "naïve" 04:30 : Décomposer et réassembler les flux dans un flux maître 07:36 : Schéma récapitulatif 07:53 : Code de la solution (exhaustMap, switchMap & stream projection) 08:11 : Conclusion
cette vidéo est inspirée de fait réel
vous pouvez vous économiser du sang et
des larmes et de la transpiration en la
regardant ce que je vous propose c'est
de raisonner sur une problématique de
code asynchrone HTTP complexe pour un
vrai projet un peu en live et vous
montrer un peu la réflexion qui permet
de résoudre ce problème le problème il
est très simple c'est l'IHM que vous
avez à l'écran vous avez un formulaire
avec des critères de recherche très bien
l'utilisateur peut passer des commandes
et faire ses listes de courses et en
dessous vous affichez des résultats dans
un tableau jusque là tout va bien
quoique le plus intéressant ici ça va
être l'ajout d'une couche de pooling
c'est-à-dire que les données dans le
tableau vont devoir être poulé toutes
les 15 secondes d'accord toutes les 15
secondes les données affichées à l'écran
doivent être rafraîchi en faisant un
appel au serveur ce qui va se passer ici
dans cet exercice c'est que tout va bien
jusqu'à ce qu'on attaque une des
problématiques les plus infernal quand
on démarre ou même quand on continue
dans le développement ça va être la
problématique des race condition prenons
un exemple imagine qu'il n'y ait même
pas de pooling dans cet écran
l'utilisateur va envoyer une première
requête en renseignant des informations
dans le formulaire on va envoyer cette
requête cette requête est en cours si
pendant ce temps l'utilisateur
finalement change ses critères de
recherche en envoyant une deuxième
requête et bien une autre requête va
partir en plus de celle qui est déjà en
cours et le problème c'est que ces deux
requêtes vont peut-être être inversé au
niveau du résultat c'est-à-dire que
l'utilisateur quand il a passé sa deuxè
liste de courses sa deuxème demande et
bien la requête va être résolue
extrêmement vite mais la première
requête qui est toujours en cours va
arriver après cette problématique est
infernale quand vous faites du code avec
de l' syynchrone et c'est une
problématique de race condition ce qu'on
voudrait ici c'est garantir que les
requêtes arrivent dans le même ordre que
ce que l'utilisateur a demandé et
annuler la première requête qui était
déjà en cours pour dire cette requête
nous intéresse plus maintenant on veut
mpper sur la nouvelle requête cette
problématique de ris condition elle est
résolue de manière prédictible à 100 %
par quatre opérateurs rxjs j'ai déjà
fait une vidéo là-dessus et je vous
invite à aller la voir si vous
travaillez avec cette librairie et la
programmation réactive pour ne plus
avoir à vous soucier des race condition
c'est terminé ce problème a été résolu
ce qui est intéressant ici c'est que on
a un problème un peu plus compliqué que
de choisir entre switch map ou exust map
pourquoi imaginons qu'on est la seconde
14 à T0 l'utilisateur a commencé à
envoyer une première requête elle a été
résolue et donc dans une seconde et bien
on va voir la requête de pooling qui va
par mais si au même moment à la 14e
seconde l'utilisateur décide de changer
les critères de recherche dans le
tableau et bien vous avez une requête
qui va partir et quelques millisecondes
plus tard vous allez avoir la requête du
pooling qui va partir et la question qui
est intéressante c'est que dans ce cas
est-ce qu'on veut annuler le pooling
pour pouvoir faire prioriser la requête
de l'utilisateur ou alors l'inverse on
prend pas en compte la requête
d'utilisateur on dit c'est la requête du
pooling qui fait sens dans ce cas bien
évidemment c'est les demandes de
l'utilisateur qui sont prioritaires on
va pas faire un pooling sur des critères
de recherche qui qui sont périmés mais
le problème si on fait ça ça veut dire
queà chaque fois que l'utilisateur passe
une nouvelle demande et bien il faut
annuler le pooling précédent et en
démarrer un nouveau qui lui-même aura
des requêtes et ces requêtes de pooling
doivent elles-mêmes être gérées dans le
temps de manière prédictible si au bout
de 16 secondes la requête du pooling est
toujours pas revenue qu'est-ce que vous
faites du nouveau pooling qui part
est-ce que vous attendez la requête du
premier trigger de pooling vous en
démarrez une autre pour être sûr d'avoir
des données fraîches c'est une
problématique rx s et ça c'est une
problématique de traitement asynchrone
qui est plus que du débutant même si
c'est pas non plus infaisable donc une
des premières manières de modéliser ce
problème ça serait de se dire on a un
seul flux d'événement qui est du pooling
toutes les 15 secondes et par-dessus je
viens merger avec les requêtes de
l'utilisateur qui viennent à droite à
gauche mais comme on l'a vu ça va pas
fonctionner de la même manière puisque
le pooling va avoir une stratégie
exhaust map c'est-à-dire que si au bout
de 16 secondes on a toujours pas obtenu
la réponse ce qu'on va vouloir faire
c'est ne pas prendre en compte ce
nouveau pooling et attendre que la
première requête est terminée et à la
prochaine itération à 30 secondes 45
secondes là on balancera une nouvelle
requête pour la stratégie des événements
utilisateur on a plutôt une logique de
switch map c'est-à-dire que cette
fois-ci quand l'utilisateur va en
saccader faire trois demandes
différentes avant qu'on a les réponses
du backend et ben ce qu'on va vouloir
faire cette fois c'est pas annuler les
demandes d'utilisateur c'est annuler les
requêtes en cours qui correspondent plus
à ce qu'il a demandé donc cette fois-ci
c'est un switch map la question c'est
concrètement dans votre code qu'est-ce
que vous devez écrire pour exprimer ça
et bien je vous mets je vais faire un
petit dessin ça vaut ce que ça vaut mais
l'idée ça va être de décomposer les flux
et de les réassembler pour créer le flux
master final donc vous avez un premier
flux qui va être les demandes de
l'utilisateur donc ça va être un flux
infini d'accord ça potentiellement ça se
termine jamais à moins que l'utilisateur
quitte la page et ici on va dire que
l'utilisateur va faire trois demandes
comme ceci je sais pas si vous voyez ce
qu'on va vouloir faire c'est qu'à chaque
fois que l'utilisateur balance un
événement on va vouloir projeter sur un
autre flux qui est de démarrer un
poolling donc ici on va projeter sur un
flux qui a lieu de manière prédictible
toutes les 15 secondes d'accord comme
ceci après je vous mettrai le code pour
que ce soit plus clair voyez donc on a
un flux d'événement on va le projeter
dans un autre flux et ce flux toutes les
15 30 ou 45 secondes on va lui-même le
projeter dans une requête HTTP d'accord
et ici on a un flux fini qui est la
requête HTTP c'est un début une fin et
quand le flux ai il se complitent les
deux autres flux ne se complitent pas
puisque le flux et les événements
utilisateurs peuvent potentiellement
avoir lieu à l'infini on peut tout le
temps les écouter vous avez donc ici une
espèce de cascade je sais pas si vous
voyez bien vous avez le flux des
événements utilisateurs le pooling à
démarrer à chaque fois et la requête
HTTP tout ça doit être construit pour
que l'affichage à la fin pour
l'utilisateur soit tout le temps
cohérent avec ce qu'il a demandé et avec
des données rafraîchies ce qui est
intéressant et ce que vous devez faire
c'est que vous avez construire un flux
de de flux d'événement utilisateur et
vous allez ici positionner un switch map
entre les events et le pooling avec les
roquettes HTTP donc là je vais mettre un
switch map entre ce flux et ce truc et
ce Tru vous allez pouvoir le construire
avec
timer qui est l'équivalent d'intervalle
en rxjs pour dire le timer toutes les 15
secondes et vous allez pipe ici et vous
allez positionner le exhaust map entre
le pooling et la requette HTT
d'accord donc ici vous avez trois flux
avec deux projections une switch map et
une exhaust map ce qui se passe ici
c'est que tant que l'utilisateur n'a pas
déclenché un seul événement il y a pas
une requête HTTP qui part c'est tant que
l'utilisateur a pas saisi des critères
de recherche ça nous intéresse pas plus
que ça d'effectuer une requête vous avez
un formulaire vide tableau vide à partir
du moment où l'utilisateur déclenche un
premier critère de recherche on va
projeter sa demande sur un autre flux
qui est un timer qui va faire des
requêtes HTTP si on remonte à l'envers
le exhaust map va s'assurer que on fait
un refresh que quand on en a besoin et
que si les requêes d'avance sont
toujours dans le pipe pour le refresh et
ben on déclenche pas de nouvell requêes
donc là ce problème est résolu et on va
faire un switch map pour redémarrer un
pooling qui va chercher les bonnes
données sur les derniers critères de
recherche de l'utilisateur d'accord donc
je remets en place je me resubscribe sur
un pooling vers le backend qui est
toujours à jour avec les demandes de
l'utilisateur et comme j'ai un switch
map mon pooling en cours il est annulé
quand la demande d'utilisateur est
terminée voilà donc je sais pas si c'est
très clair en gros l'idée c'est un peu
ce schéma et ce qui vous permet de
résoudre ce problème très complexe c'est
de décomposer en flux vous avez un flux
pour le pooling un flux pour les
roquettes HTTP infux pour les événements
utilisateurs quels sont les flux finis
ou infinis et comment je veux les
projeter avec exos map ou switch map
entre eux donc ça c'est un workshop très
intéressant je me le suis noté pour
progresser sur les problématiques de de
traitement de donné asynchrone la
programmation réactive rxjs c'est un
excellent entraînement ce genre
d'exercice j'espère que cette vidéo peut
servir plus ou moins si vous rencontrez
un problème similaire voilà merci de
m'avoir écouté j'espère que la vidéo
vous a plu et si vous cherchez à vous
professionnaliser dans votre production
de code actuellement et bien voici trois
manières dont je peux vous aider
gratuitement premièrement vous pouvez
repasser sur la chaîne quand vous en
avez besoin j'essaie de produire une
vidéo sur un sujet d'ingénierie
logicielle par semaine pas besoin de
vous abonner deuxièmement vous pouvez
interagir avec la chaîne en mettant un
petit pouce ou poser une question en
commentaire ça va permettre de nous
faire connaître de donner du poids à
cette chaîne pour demain interviewer des
pointures dans notre industrie un techit
chez Google un architecte chez Netflix
qu'on pourra interviewer et mettre la
vidéo directement sur la chaîne donc
vous pourrez en bénéficier et puis enfin
troisièmement vous retrouverez en
description sous la vidéo un workshop
pour vous préparer pour votre première
mission sur angular en entreprise en
trois soirées de code le workshop est en
libre accès c'est le le premier lien en
description de la vidéo et si vous
voulez aller plus loin je propose un
abonnement payant où je montre
concrètement comment je code en filmant
mon vs code et si ça vous intéresse vous
pouvez vous faire payer cet abonnement
par votre employeur en tout cas merci de
m'avoir écouté à bientôt pour une
prochaine vidéo et bon code senior d'ici
là Ciao