reactivex

73
Rx Florent Le Gall @flornt Développeur Full Stack

Upload: florent-le-gall

Post on 18-Jan-2017

1.077 views

Category:

Engineering


0 download

TRANSCRIPT

Rx

Florent Le Gall @flornt Développeur Full Stack

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

2

• ReactiveX : les extensions réactives • Le principe général • Observer / Observable • Les opérateurs courants • Cold vs Hot • Les sujets • Les schedulers

Au programme

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

3

• Pourquoi ? • Besoin de scalabilité : de plus en plus de

traitements sont distribués, l’approche synchrone ne suffit plus.

• Besoin de temps réel : répondre immédiatement à une demande

• Besoin de faciliter les changements dans le code: découplage / composabilité / flexibilité

La programmation réactive ?

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

4

• Pour quels cas d’utilisation ? • Backend : • Architectures micro-services • Temps réel • Haute scalabilité

• Frontend : • Temps réel : monitoring, finance • Applications très complexes

La programmation réactive ?

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

5

ReactiveX• Un projet originellement issu du “Cloud

Programmability Group at Microsoft” • Des contributeurs de : • Netflix, Microsoft, Google, Trello

• Des principes communs : • Observer, Observable, Opérations,

Subject, Scheduler…

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

6

ReactiveX• Des bindings pour de nombreux langages et

plateformes : • RxJava, RxJs, Rx.Net, RxScala, RxClojure,

RxCpp, Rx.rb, RxPy, RxGroovy, RxJRuby, RxKotlin, RxSwift, RxNetty…

• Des APIs différenciées : • Pour des styles de programmation

différents • Pour des contraintes différentes

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

7

ReactiveX• La documentation générale : • http://reactivex.io/

• La documentation par langage • RxJS : https://github.com/Reactive-

Extensions/RxJS/tree/master/doc

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

8

Les extensions réactives

Une seule valeur Plusieurs valeurs

Synchrone / Pull Fonction Itérable / Itérateur

Asynchrone / Push Promesse / Future Observable

Un paradigme différent

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

9

Les extensions réactives

Iterable (pull) Observable (push)

Récupérer des données T next() onNext(T)

Découvrir une erreur T next() throws Exception onError(Exception)

complete if(!hasNext()) { return;} onCompleted()

Un paradigme différent

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

10

Le pattern Observer / Observable• Observable : • “Observable is a function that when

invoked return 0 - ∞ values between now and the end of times.” • Paul Taylor | Reactive 2015

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

11

Le pattern Observer / Observable• Observer : • Une interface avec 3 méthodes

principales : • onNext() : Récupère une donnée • onCompleted() : Termine le traitement • onError(Exception) : Termine le

traitement en erreur

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

12

Le pattern Observer / Observable• Observer : • En pratique on n’appelle pas ces

méthodes soit même. • On crée un observateur via : • Rx.Observer.create([onNext], [onError],

[onCompleted])

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

13

Le pattern Observer / Observable• Observable : • Permet d’enregistrer des observateurs • Rx.Observable.prototype.subscribe([obs

erver] | [onNext], [onError], [onCompleted])

• Rx.Observable.prototype.forEach([observer] | [onNext], [onError], [onCompleted])

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

14

Le pattern Observer / Observable• Observable : • Mais pour l’instant, c’est juste le design

pattern Observer avec la gestion des erreurs et des fins de traitement ?

• La richesse de Rx, ce sont ses opérateurs • Transformer, combiner, manipuler et

travailler sur les séquences reçues.

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

15

Le pattern Observer / Observable• Les marble diagrams

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

16

Comment créer un observable ?• À l’aide des opérateurs de création • Implémentés sous forme de méthodes

statiques sur Observable

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

17

Créer : Create

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

18

Créer : From

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

19

Créer : From• Permet de créer un observable depuis : • fromCallback(): Une callback • fromEvent(input, ‘change’): Un évènement

HTML • fromNodeCallBack() : Une callback Node • fromPromise() : Une promesse • of(1,2,3) : Une liste de valeurs • ofObjectChanges(obj) : Les changements

observés par obj.observe().

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

20

Créer : Just

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

21

Créer : Empty

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

22

Créer : Never

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

23

Créer : Throw

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

24

Créer : Timer

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

25

Créer : Interval

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

26

Créer : Repeat

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

27

Créer : Range

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

28

Comment transformer ?• À l’aide des opérateurs de transformation • Implémentés sous forme de méthodes sur

Observable • Ces méthodes renvoient toutes un

observable

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

29

Transformer : Map

• Prend en paramètre une fonction qui : • Reçoit un item • Renvoie un item transformé

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

30

Transformer : FlatMap

• Prend en paramètre une fonction qui : • Reçoit un item • Renvoie un observable

• Aplatit (flatten) le résultat

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

31

Transformer : FlatMap

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

32

Transformer : FlatMap

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

33

Transformer : FlatMap• C’est une monade !

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

34

Transformer : Scan

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

35

Filtrer : Filter

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

36

Filtrer : Distinct

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

37

Comment combiner ?• Opérateurs de fusion (merge) • Implémentés sous forme de méthodes sur

Observable • Ces méthodes: • Prennent en paramètre un autre

observable • Renvoient un observable

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

38

Combiner : Merge

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

39

Combiner : Zip

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

40

Comment agréger ?• Opérateurs d’agrégation • Implémentés sous forme de méthodes sur

Observable • Ces méthodes renvoient un observable • Qui émettra deux évènements : • onNext() avec la valeur finale • onCompleted() • Ou bien seulement onError() en cas

d’erreur

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

41

Agréger : Count

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

42

Agréger : Max/Min/Sum/Average

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

43

Agréger : Reduce

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

44

• Que faire quand on reçoit beaucoup plus d’évènements qu’on ne peut en traiter ? • Attendre la fin de la tempête et traiter à

ce moment là ? • Échantilloner ? • Regrouper les évènements ? • Appliquer de la conflation ?

BackPressure

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

45

BackPressure : Throttle/Debounce

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

46

BackPressure : Buffer

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

47

BackPressure : Sample

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

48

ControlledObservable

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

49

Hot or Cold ?• Un observable “chaud” : • N’attend pas qu’un observateur se

connecte pour émettre • À la connexion, on ne reçoit que les

nouveaux évènements • Exemple : • Un flux d’information (logs, finance …) • Des évènements IHM

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

50

Hot or Cold ?• Un observable “froid” : • Attend qu’un observateur se connecte

pour émettre • À la première connexion, l’observateur

reçoit tous les évènements • Exemple : • Une lecture de fichier • Une requête Http • Une requête SQL

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

51

“Cold” : risque d’effets de bord• Un observable “froid” peut être soumis aux

effets de bord lors de la souscription

• Lorsque l’on appelle subscribe(), on doit garantir que chaque observateur va obtenir l’ensemble des résultats

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

52

“Cold” : risque d’effets de bord• Comment garantir ce contrat ? • Conserver tous les évènements ? • Faisable, mais coûteux

• Relancer l’opération à chaque connexion d’un observateur ? • C’est l’implémentation choisie par la

plupart des observables “froids” • Il y’a donc un effet de bord possible

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

53

“Cold” : risque d’effets de bord• http://davesexton.com/blog/post/Hot-and-

Cold-Observables.aspx • https://social.msdn.microsoft.com/Forums/

en-US/14a62f80-a010-4e60-b852-c7991a57fb07/its-hard-to-reason-about-publish

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

54

Cold -> Hot ?• Convertir un observable “froid” en “chaud” • Publish

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

55

Hot -> Cold ?• Convertir un observable “chaud” en “froid” • Defer • Rx.Observable.defer(observableFactory)

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

56

Subject• À la fois un observable et un observateur • Comme c’est un observateur : • Il peut s’abonner à un ou plusieurs

observables • Comme c’est un observable, il peut ré-

émettre les évènements qu’il observe et en renvoyer d’autres.

• Les sujets sont des observables “chauds”

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

57

AsyncSubject• AsyncSubjet permet de capturer la valeur

finale d’un traitement asynchrone

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

58

AsyncSubject

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

59

AsyncSubject

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

60

• BehaviorSubject est utilisé pour implémenter un état

BehaviorSubject

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

61

BehaviorSubject

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

62

BehaviorSubject

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

63

• ReplaySubject est utilisé pour implémenter un historique

ReplaySubject

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

64

Schedulers • Les schedulers sont utilisés pour définir un

contexte d’exécution • Dans le monde Java / .Net • Dans quel thread est notifié mon

observable / observateur ? • Dans le monde JS • Execution immédiate ? • setTimeout ? • requestAnimationFrame ?

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

65

Schedulers - ObserveOn• Définit le contexte d’execution des

observateurs d’un observable

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

66

Schedulers - SubscribeOn• Définit le contexte d’execution des

opérateurs d’un observable

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

67

• Quelques tutoriels: • https://github.com/jhusain/learnrxjava/

(Jafar Husain | Netflix) • http://reactivex.io/learnrx/ (JS - Jafar

Husain | Netflix) • https://github.com/mattpodwysocki/

RxJSKoans (JS)

Pour approfondir

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

68

• Une publication • Your mouse is a database (Erik Meijer /

Microsoft) : http://queue.acm.org/detail.cfm?id=2169076

• Une vidéo • Asynchronous Javascript at Netflix (Jafar

Husain) : https://www.youtube.com/watch?v=XRYN2xt11Ek

Pour approfondir

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

69

• Des MOOC • http://app.pluralsight.com/courses/

reactive-programming-java-8-rxjava • https://www.coursera.org/course/reactive

Pour approfondir

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

70

• Le pattern Observable/Observer peut s’appliquer à tout

• Rx est un outil très riche • … qui demande une certaine maîtrise

Pour conclure

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

71

• Anatomie d’une application frontend RxJS

Next time !

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC + AKAMIS

72

Questions

?

Merci!