paris scala user group #43 - spray (magnet pattern) + rxscala / elasticsearch

Post on 30-Jun-2015

2.063 Views

Category:

Technology

4 Downloads

Preview:

Click to see full reader

DESCRIPTION

Retour d'experience sur l'utilisation de spray dans le cadre de Mogobiz. Explication de la technique du "Magnet Pattern" et présentation des bénéfices de l'utilisation de Rx. http://j.mp/psug43Xebia

TRANSCRIPT

Spray / RxScala / ElasticSearch

Paris  Scala  User  Group  #43  !!!!

Email:                mourad.dachraoui@ebiznext.com  

TwiAer:          @ze_dach

Mourad  DACHRAOUI

Contexte

Mogobiz

http://www.jahia.com/home/products/ecommerce-factory.html

SPRAY ?

Ensemble  de            bibliothèques    pour    la  construc>on  

d’API  RESTful  basé  sur  Akka

spray-http

spray-can

IO STACK

spray-routing

spray-routing

spray-routing

spray-routing

hAp://spray.io/blog/2012-­‐12-­‐13-­‐the-­‐magnet-­‐paAern  

Place au code

ObjecLf:      • DSL  composé  de  la  foncLon  host  • Masquer  la  complexité  de  host    

ObjecLf:      • DSL  composé  de  la  foncLon  host  • Masquer  la  complexité  de  host    

Notre  méthode  host  prend  comme  

paramètre  plusieurs  types  en  entré.

ObjecLf:      • DSL  composé  de  la  foncLon  host  • Masquer  la  complexité  de  host    

Notre  méthode  host  prend  comme  paramètre  

en  entrée  plusieurs  types  en  entré.

Il  faut  le  converLr  implicitement  

en  Int  (logique  applicaLve  pour  

notre  exemple)  

=>  l'evidence  ev

ObjecLf:      • DSL  composé  de  la  foncLon  host  • Masquer  la  complexité  de  host    

Notre  méthode  host  prend  comme  paramètre  

en  entrée  plusieurs  types  en  entré.

Il  faut  le  converLr  implicitement  

en  Int  (logique  applicaLve  pour  

notre  exemple)  

=>  l'evidence  ev

ObjecLf:      • DSL  composé  de  la  foncLon  host  • Masquer  la  complexité  de  host    

Notre  méthode  host  prend  comme  paramètre  

en  entrée  plusieurs  types  en  entré.

Il  faut  le  converLr  implicitement  

en  Int  (logique  applicaLve  pour  

notre  exemple)  

=>  l'evidence  ev

!<console>:24:  error:  type  mismatch;    found      :  SprayTestsNoMagnet.Route    required:  String  =>  Int                        new  Route  {}                        ^

!<console>:24:  error:  type  mismatch;    found      :  SprayTestsNoMagnet.Route    required:  String  =>  Int                        new  Route  {}                        ^

val  route  =  host("SprayTestsNoMagnet")  (  new  Route  {}  )  =

val  route  =  host("SprayTestsNoMagnet")  (  new  Route  {}  )  =

Solu>on  =>  Appel  intermédiaire

scala>  import  SprayTestsNoMagnet._  

import  SprayTestsNoMagnet._  

!scala>  tmpHost  

res1:  SprayTestsNoMagnet.Route  =>  SprayTestsNoMagnet.Route  =  <funcLon1>  

!tmpHost  (new  Route  {})  

res2:  SprayTestsNoMagnet.Route  =  $anon$1@6f5c0b7b  

!host("SprayTestsNoMagnet")  (stringToInt)  (new  Route  {})  

res4:  SprayTestsNoMagnet.Route  =  $anon$1@521352d8

Nous  ne  pouvons  pas  nous  contenter  de  ce/e  solu1on  si  nous  é1ons  entrain  d'écrire  un  DSL

==>  Magnet  «  paMern  »  qui  résout  entre  autre  ceMe  probléma>que

Nous  ne  pouvons  pas  nous  contenter  de  ce/e  solu1on  si  nous  é1ons  entrain  d'écrire  un  DSL

//  Notre  nouveau  Type  HostMagnet  est  bien  sensé  renvoyer  la  même  foncLon  Route  =>  Route

//  Notre  nouveau  Type  HostMagnet  est  bien  sensé  renvoyer  la  même  foncLon  Route  =>  Route

//  Le  premier  implicit  est  une  conversion  implicite  qui  nous  permet  d'obtenir  //  une  instance  HostMagnet  à  parLr  d'une  string  ,  en  l'occurrence  "mogobiz.io"

//  Notre  nouveau  Type  HostMagnet  est  bien  sensé  renvoyer  la  même  foncLon  Route  =>  Route

//  Le  premier  implicit  est  une  conversion  implicite  qui  nous  permet  d'obtenir  //  une  instance  HostMagnet  à  parLr  d'une  string  ,  en  l'occurrence  "mogobiz.io"

 //  host  prend  un  paramètre  de  type  HostMagnet    //  et  retourne  une  instance  de  HostMagnet

//  magnet.apply()

scala>  import  SprayTestsWithMagnet._  import  SprayTestsWithMagnet._  !scala>  val  route  =  host("mogobiz.io")  {            |    new  Route  {}            |      }  route:  SprayTestsWithMagnet.Route  =  $anon$1@51f347a  !scala>  val  x  =    host("mogobiz.io")  x:  SprayTestsWithMagnet.Route  =>  SprayTestsWithMagnet.Route  =  <function1>

• Finaliser  une  requête  HTTP  

• DSL  ==>  «  complete  »  

• Plusieurs  manière  de  finaliser  une  requête  HTTP  ==>  Surcharger  «  complete  »

Type  erasure

LimitaLon  pour  les  types  paramètrés  

Nice,  but  show  me…

…  some  Magnet  PaMern  in  Spray-­‐rou>ng  

CeAe  direcLve  est  uLlisée  au  sein  d'une  val  route  qui  est  de  Type  Route  (spray-­‐rouLng).

CeAe  direcLve  est  uLlisée  au  sein  d'une  val  route  qui  est  de  Type  Route  (spray-­‐rouLng).

?

pathPrefix  est  une  foncLon  qui  prend  en  paramètre  un  PathMatcher  et  qui  nous  renvoi  un  objet  de  type  Directive.    !(cf.    spray-­‐rouLng/src/main/scala/spray/rouLng/direcLves/PathDirecLves.scala)

pathPrefix  est  une  foncLon  qui  prend  en  paramètre  un  PathMatcher  et  qui  nous  renvoi  un  objet  de  type  Directive.    !(cf.    spray-­‐rouLng/src/main/scala/spray/rouLng/direcLves/PathDirecLves.scala)

PathMatcher  défini  un  implicite  qui  converL  un  String  en  PathMatcher  (conversion  d’  "acount"  en  une  instance  de  PathMatcher)  (cf.    spray-­‐rouLng/src/main/scala/spray/rouLng/PathMatcher.scala)

pathPrefix  est  une  direcLve,  qui  prend  en  paramètre  une  closure  de  type  Route,  Et  retourne  une  Route.

pathPrefix  est  une  direcLve,  qui  prend  en  paramètre  une  closure  de  type  Route,  Et  retourne  une  Route.

==>  Conver1r  implicitement  la  Directive  en  une  fonc1on  qui  prend  un  paramètre  de  type  Route  et  renvoi  un  résultat  de  Type  Route    (Route  =>  Route)

(cf.  spray-­‐rouLng/src/main/scala/spray/rouLng/DirecLve.scala)

Il  prend  en  paramètre  une  DirecLve  ET  un  Converter  en  implicite.  !L’  ApplyConverter  en  implicite  est  un  type  paramétré,  donc  il  dépend  du  type  de  DirecLve  en  entré.  

(cf.  spray-­‐rouLng/src/main/scala/spray/rouLng/DirecLve.scala)

(cf.  spray-­‐rouLng/src/main/scala/spray/rouLng/ApplyConverter.scala)

l'ApplyConverter  est  l'équivalent  de  notre  évidence  de  l'exemple  précédant  qui  va  converLr  la  DirecLve[L]  en  Route

(cf.  spray-­‐rouLng/src/main/scala/spray/rouLng/DirecLve.scala)

(cf.  spray-­‐rouLng/src/main/scala/spray/rouLng/ApplyConverter.scala)

ApplyConverter  va  renvoyer  un  In  qui  est  en  fait  une  Route.  Le  pimpApply  renvoi  une  foncLon  hac.In  =>  Route    !=>  Nous  avons  donc  notre  Type  de  retour  Route  =>  Route

• Notre  Objet  Magnet  est  la  Directive  

• pathPrefix  est  exécuté  une  seule  fois;  lors  du  chargement  de  

l'applicaLon  (Spray)  transformé  en  Directive  

• La  Directive  est  transformée  en  une  foncLon  qui  prend  en  

paramètre;  la  Route  entre  accolade  

• Tout  ce  qui  produit  une  Directive  est  exécuté  au  chargement  de  

spray  (get,  path,  pathPrefix,  completed,  )  

• Spray  va  stocker  ceAe  informaLon  et  ne  va  pas  l'évaluer  à  chaque  fois.    

• Par  contre,  les  définiLons  des  closures  seront  chargés  mais  non  

exécuté.  

RxJava-Sclala

spray-client

spray-client• non  adapté  dans  certain  cas  d’uLlisaLon  (Mogobiz)  

• Appel  de  plusieurs  Index  ElasLcSearch  en  parallèle    

• Appliquer  des  traitement  (Suppression  des  langues,  calcul  du  prix)  

• ComposiLon  +  dépendance    des  Futures  

==>  Complexité  d’implémentaLon    

==>  Nous  perdons  la  simplicité  du  DSL  spray-­‐client  

RxJava• ImplémentaLon  par  Nexlix  du  Projet  Rx  (ReacLve  Extensions)  hAp://codeplex.com/  de  Microsoy    

• Bibliothèque  permeAant  de  composer  des  programmes  événemen>els  asynchrone,  via  l’uLlisaLon  de  séquences  observables.

RxJava

Resources• Ben  Christensen.  “FuncLonal  ReacLve  Programming  in  the  Nexlix  API.”  hAp://fr.slideshare.net/InfoQ/funcLonal-­‐reacLve-­‐programming-­‐in-­‐the-­‐nexlix-­‐api    

• Mathias  Doenitz.  “Spray:  REST  on  Akka  (Scala  Days).”  hAp://fr.slideshare.net/sirthias/spray-­‐rest-­‐on-­‐akka-­‐12616908    

• “Spray  |  Blog »  The  Magnet  PaAern.”  hAp://spray.io/blog/2012-­‐12-­‐13-­‐the-­‐magnet-­‐paAern/  

Resources• “Spray  |  DocumentaLon.”  hAp://spray.io/documentaLon/    

• “Implicit  Parameters  -­‐  Scala  DocumentaLon.”  hAp://docs.scala-­‐lang.org/tutorials/tour/implicit-­‐parameters.html    

• “Scala  IO  2013  =>  Spray :  REST  on  Akka  -­‐  Blog.roddet.com.”  hAp://blog.roddet.com/2013/10/scalaio-­‐2013-­‐spray-­‐rest-­‐on-­‐akka/

Medias• “Sciences  Naturelles:  Horseshoe-­‐Magnet-­‐Red-­‐Silver-­‐Iron-­‐Filings-­‐Highres-­‐.”hAp://mirror-­‐us-­‐ga1.gallery.hd.org/_c/natural-­‐science/_more2008/_more12/horseshoe-­‐magnet-­‐red-­‐silver-­‐iron-­‐filings-­‐highres-­‐AHD.jpg.html    

• “Willy  Wonka”  hAp://memegenerator.net/Willywonka/capLon    

• “API  Safe  and  Easy  Aquarium  Spray”  hAp://www.amazon.com/API-­‐Safe-­‐Aquarium-­‐Spray-­‐8-­‐Ounce/dp/B001D728VI

Merci

Q&A

top related