Atelier RxJava, les mains dans le code (DevoxxFr2015)
Slides pour l'atelier de découverte de RxJava par la pratique, une migration d'application legacy. Le squelette du code est disponible sur http://bit.ly/PracticalRx
@simonbasle #PracticalRxJava Le Plan (sans accroc) •Présentation de RxJava •L'application legacy •8 étapes de migration • opérateurs utiles • instructions et pièges à éviter ● Q&A
@simonbasle #PracticalRxJava Pourquoi? • Cas d’utilisations: Asynchrone, Event Based, IO, Temps de traitement, Concurrence -> n'importe quelle opération qui peut Bloquer • Bloquer c’est Mal, voyez? • Toi aussi deviens asynchrone, composable, lisible.
@simonbasle #PracticalRxJava Vous avez déjà essayé? •Etre Async c’est pas si simple • Java Future • Callback • Entre la gestion d’erreur, d’exceptions, annulations, synchro, threading • Et on n’a pas encore abordé la lisibilité du code….
@simonbasle #PracticalRxJava Simplicité et Composabilité •Observable = flux connectable à un Observer • Un Observer a 3 actions: onNext, onError, onCompleted • Le flux est composable et permet d’être plus descriptif dans ce que l’on veux faire • transformer • filtrer • combiner • gérer les erreurs de manière avancée • intégrer la notion de temporalité
@simonbasle #PracticalRxJava Doge Mining Pool UI Rest Controller Rest Controller Rest Controller Rest Controller Service Service Service External API External API External API DB L E G A C Y
@simonbasle #PracticalRxJava Attention •Certains usages des services continuent de compiler • bien vérifier non seulement les erreurs de compilation mais aussi les usages de chaque méthode...
@simonbasle #PracticalRxJava Services à Migrer •UserService • findAll sera pour l'instant adapté naïvement (Observable.from(...)) • composer sur findAll pour findById / findByLogin •SearchService
@simonbasle #PracticalRxJava StatService.getAllStats •pour chaque utilisateur • récupérer son hashrate • récupérer son nombre de pièces • combiner les deux pour créer un UserStat
@simonbasle #PracticalRxJava Problème? •StatService.lastBlockFoundBy • implem à toute épreuve (choisir un utilisateur au hasard) • oui mais si on voulait le tenter sans connaître le nombre d'utilisateurs à l'avance?
@simonbasle #PracticalRxJava Le Plan •Générer un index au hasard (dans une limite à la louche) •Réssayer jusqu'à 4 fois si c'est trop grand •En dernier recours retourner un User créé pour l'occasion (utilisateur banni?)
@simonbasle #PracticalRxJava Réponse Asynchrone •Retourner du DeferredResult •Subscribe sur les flux • onNext: injecter le résultat via setResult • onError: créer une DogePoolException et l’injecter via setErrorResult •retourner le DeferredResult immédiatement
@simonbasle #PracticalRxJava Controleurs à Améliorer •AdminController (simple) •IndexController (plus compliqué) • user du zip, flatMap, single pour détecter les mauvais utilisateurs... •UserProfileController (plus compliqué)
@simonbasle #PracticalRxJava ExchangeRateService •Appelle deux API externes • Taux de change du Doge vers Dollar • Taux de change Monnaie A vers Monnaie B •La combinaison des deux permet d'obtenir le Doge vers Monnaie B •Appels REST
@simonbasle #PracticalRxJava Opérateurs Utiles •Observable.create • pour wrapper l'appel • capturer les RestClientException et en faire des DogePoolException, notamment pour les timeouts •zipWith (idem zip)
"cette API gratuite de taux de change plante trop souvent, fait en sorte de basculer vers une API alternative payante quand c'est le cas" - le Product Owner
"cette API gratuite de taux de change plante trop souvent, fait en sorte de basculer vers une API alternative payante quand c'est le cas" - le Product Owner
"ah oui et si tu pouvais comptabiliser les coûts de ces appels ça serait top" - le Product Owner, se versant un café Much Surprise Such Requirements wow
@simonbasle #PracticalRxJava Le Plan •Ajouter de quoi enregistrer un coût dans AdminService •Ajouter une méthode à ExchangeRateService • utiliser la propriété exchange.nonfree.api.baseUrl •Basculer grâce à OnErrorResumeNext •Utiliser les effets de bord • logger les appels basculés, enregistrer l'impact en coût
@simonbasle #PracticalRxJava SideCar Motocross CC-BY-ND Jean-Daniel Echenard on Flickr https://www.flickr.com/photos/34804353@N02/6981852262/ Fusion Panda CC-BY-NC Domonated on DeviantArt http://domonated.deviantart.com/art/dragon-ball-z-fusion-298515441 Sandpit CC0 http://en.wikipedia.org/wiki/Sandpit#/media/File:Sandpit.jpg DBZ Cosplayer at DaishoCon CC-BY ygktech on Flickr https://www.flickr.com/photos/ygktech/15905787661/ Tumbeast Gnawing on Servers CC-BY Matthew Inman http://en.wikipedia.org/wiki/Error_message#/media/File:Tumbeasts_servers.png Kane Cleaning Supplies CC-BY collinanderson on Flickr https://www.flickr.com/photos/collinanderson/2912308728 Chain CC0 http://commons.wikimedia.org/wiki/File:Chain_1.JPG Marble Diagrams (all) CC-BY ReactiveX Documentation http://reactivex.io/ Office Space still Copyright 20th Century Fox Broken Keyboard CC-BY Santeri Viinamäki on Wikimedia http://upload.wikimedia.org/wikipedia/commons/0/02/Broken_keyboard.jpg Black Hole with Corona CC0 Public Domain - NASA http://upload.wikimedia.org/wikipedia/commons/8/89/PIA16695-BlackHole- Corona-20130227.jpg Gobots Toys CC-BY Tom Prankerd on Wikimedia http://upload.wikimedia.org/wikipedia/en/f/f6/GobotToys.jpg Woman Smoking Cigar in Cuba CC-BY Tibor Végh on Wikimedia http://commons.wikimedia.org/wiki/File:Cigar_smoking_woman_in_Cuba.jpg Coffee Filter CC0 Public Domain http://pixabay.com/fr/caf%C3%A9-filtre-caf%C3%A9ine-boire-690965/ Abacus CC0 Public Domain http://pixabay.com/fr/abaque-comptent-les-math%C3%A9matiques-485704/ Trap CC-BY-SA anticiv on Flickr https://www.flickr.com/photos/anticiv/294895884/ Crédits