Rossi Oddet

Blog d'un artisan développeur

Scala IO 2013 => Patterns De Développement Pour Une Application Web Réactive Et Concurrente

Présentateurs

Fabrice Croiseaux, CEO chez InTech Luxembourg. Il anime régulièrement des podcasts NipDev.


Antoine Detante, Ingénieur chez InTech Luxembourg.



=> La description de la session ScalaIO

Le Talk !

Antoine et Fabrice sont arrivés 2nd au concours Typesafe’s Developer Contest qui a eu lieu en début d’année.

Ils ont concouru avec une application Car Race Dashboard construite avec Play! Framework qui offre en temps réel la visualisation d’un dashboard de course de voitures.

Ce talk a été l’occasion pour eux de présenter leur travail.

Une application construite avec 3 composants principaux

  • Race Simulation => un moteur qui simule le déplacement de voitures

  • Race Dashboard => Stockage des positions dans une base Mongo DB + calcul des statistiques en asynchrone + notification des résultats

  • Web Client => un client web qui affiche en temps réel l’évolution de la course

Race Simulation

Du KML en guise de circuit

Pour simuler le déplacement d’une voiture, il faut déterminer une liste de coordonnées possibles. Cette liste de coordonnées est commune à toutes les voitures lors d’une course. Elle dépend évidemment du circuit sélectionné pour la course.

La liste des points est obtenue à partir d’un fichier KML pour un circuit. A titre d’exemple, vous pouvez consulter celui du Mans ici. Ce fichier XML sera parsé pour récupérer la liste des coordonnées possibles pour une course donnée.

Curieux de voir à quoi ressemble le code Scala qui a en entrée une URL de fichier KML et en sortie une liste de points ?

TrackParserlink
1
2
3
4
5
6
7
8
9
10
11
12
13
def readTrack(url: String): List[TrackPoint] = readTrack(XML.load(url))

def readTrack(data: Elem): List[TrackPoint] = {
  val positions = (for {
    pos <- (data \\ "coordinates").text.split("\n")
    if (pos.trim.length > 0)
  } yield pos.trim).toList.map {
    pos =>
      val coordinates = pos.split(",")
      Position(coordinates(1).toDouble, coordinates(0).toDouble)
  }
  positions.zipWithIndex.map(v => TrackPoint(v._2, v._1))
}

Des acteurs, des acteurs, des acteurs

  • Race Actor => Acteur qui représente la course et qui permet de lancer toutes les voitures via un événement start. Il va aussi se charger de communiquer l’évolution des voitures au composant Race Dashboard.

  • Car Actor => Acteur qui simule le déplacement d’une voiture. Une fois l’événement start reçu du Race Actor, il va déplacer à intervalle régulier une voiture suivant la liste des points ordonnés du circuit.

Code source des acteurs

Race Dashboard

Storage Actor

Cet acteur va sauvegarder les vitesses, positions et les distances successives dans la base Mongo DB. Le driver Reactive Mongo y est utilisé.

Code Source de l’acteur

Stats Actor

Stats Actor calcule à partir des données stockées :

  • La vitesse moyenne
  • La vitesse maximale
  • Le classement général

Code Source de l’acteur

RTEventListener

Un acteur RTEventListener est instancié pour chaque client Web. Il écoute les messages du composant des acteurs Storage Actor et Stats Actor puis notifie via SSE le client web.

Web Client

Le client Web est construit avec :

A quoi ressemble l’application ?

Les slides de la présentation

Ce que j’en ai pensé

Ce talk montre un exemple d’architecture se reposant complètement sur le modèle d’acteur. Ce style d’architecture permet une organisation séparant clairement les responsabilités entre les acteurs et une communication asynchrone entre les différents composants.

Je me suis poser la question de l’intérêt de l’instanciation d’un acteur RTEventListener par client Web. Je pensais trouver 1 acteur unique pour communiquer via SSE avec tous les clients. Je comprends qu’en utilisant 1 acteur par client Web, on se donne l’opportunité de notifier de façon concurrente les clients.

Asynchronisme + séparation des responsabilités + concurrence constituent-ils les fondations d’une application web réactive ?

Vous souhaitez en savoir plus sur ce style d’architecture ? Consulter le code sur Github et surtout inscrivez-vous au cours gratuit Principles of Reactive Programming de Coursera.

Comments