Cet article est le second dans la série des articles sur mon bot Twitter qui joue et qui gagne. Dans cet article, sont abordées les technologies retenues pour le projet et les raisons de leur choix. Pourquoi et comment j’ai choisi ces bibliothèques…
La série complète :
- l’origine du projet
- l’architecture (c’est cet article !)
- l’implémentation
Architecture de l’application
Scala
Vous connaissez peut-être Scala. Ce langage fonctionnel basé sur la JVM qui fait un peu parler de lui.
Scala est un langage qui supporte nativement les extensions fonctionnelles qui viennent à peine d’arriver dans Java 8. Le langage est réputé difficile, car il met l’accent sur la possibilité d’une programmation fonctionnelle assez poussée en encourageant les patterns d’immutabilité, de pattern-matching, etc. Dans par mon expérience, il est facile de rentrer un peu dans le langage sans trop se perdre. Mais certaines bibliothèques utilisent des conceptions parfois perturbantes pour les développeurs (redéfinition d’opérateurs, objets et cast implicites). Cependant, une fois qu’on a goûté à la simplicité d’écriture du code, il est difficile de revenir vers du Java classique, et ce, d’autant plus qu’il est possible de coder en Scala sans IDE, et rien que pour ça…
Pour installer Scala, je vous suggère de passer par l’Activator. C’est un programme qui va vous permettre d’interagir avec le compilateur Scala de manière harmonieuse (un peu l’équivalent de Maven, mais avec une interface au premier abord qui est plus simple). Il contient entre autres sbt, l’outil de build et de gestion des dépendances de Scala, ainsi qu’une UI pour manipuler vos projets. sbt est un outil extrêmement puissant, mais aussi extrêmement compliqué. Sa configuration se fait avec du code Scala, ce qui laisse la porte ouverte à plein de curiosités de configuration. Mais pour un usage standard (gestion des dépendances, par exemple), il est très simple d’approche.
Une fois votre projet créé, il est possible de rajouter n’importe quelle dépendance compatible avec la JVM dans votre projet Scala.
Par exemple là, pour ce projet, mes dépendances sont :
libraryDependencies += "org.scalatest" %% "scalatest" % "2.2.4" % "test"
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.3.12"
libraryDependencies += "org.twitter4j" % "twitter4j-core" % "4.0.4"
libraryDependencies += "org.mongodb" % "casbah-core2.11" % "2.8.2"
libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging" % "3.1.0"
libraryDependencies += "org.slf4j" % "slf4j-simple" % "1.6.4"
(pour savoir quelle syntaxe utiliser pour les dépendances, j’utilise mvn repository qui me fournit directement le snippet à coller dans mon build.sbt
)
Dans ce projet, j’utilise Scala pour tout le code du projet. Il n’a aucune interface et je n’ai donc pas eu à faire de front-end Web (même si j’aurais pu y mettre Play2).
J’ai choisi Scala essentiellement parce qu’il est compatible avec l’écosystème Java. Il permet de coder rapidement grâce à sa syntaxe simple et puissante tout en bénéficiant des bibliothèques dont j’ai besoin (Twitter4J en particulier).
Mongo
Mongo, c’est le NoSQL simple par essence. Un système de stockage orienté document, une mise en œuvre rapide pour le développement et des performances en production qui sont tout à fait honorables. Nul n’est parfait et certaines limitations de Mongo peuvent être gênantes pour vous[en]. Mais pour un pet project, voir même quelque chose de plus sérieux, pensez-y.
Ici, je m’en sers pour stocker tout l’état du système, soit en gros :
- mes followers et la date à laquelle je me suis mis à les suivre,
- les statuts que j’ai déjà retweetés.
Les documents sont des documents JSON, qui sont ensuite stockés dans Mongo sous format binaire. C’est assez facile à manipuler et il existe des clients plutôt sympathiques pour aller voir dans le Mongo (oui, je suis sous OSX).
J’ai choisi Mongo parce qu’il me faut une seule ligne de commande pour démarrer un démon sur ma machine avec une base vide où que je sois.
Akka
Akka est le framework pour construire des applications concurrentes et hautement disponibles en Scala (et en Java !). C’est une bibliothèque qui permet d’avoir des acteurs dans son code. En plus de cette « simple » fonctionnalité, Akka supporte le routage sur un cluster d’acteurs, la récupération en cas d’échec et quantités d’autres petits bonus…
Un acteur est ainsi une primitive qui va répondre à des messages pour faire des traitements et ensuite envoyer d’autres messages.
L’objectif est donc de découper le pipeline de traitement en une suite plus ou moins longue de messages qui seront ensuite échangés entre les acteurs.
L’avantage de ce système, notamment lors des phases de mise au point, est qu’il est facile de tester individuellement la réponse de chaque acteur pour chaque message, ou bien même de n’utiliser certains messages que pour le développement. C’est très puissant et Akka nous facilite considérablement la vie.
J’ai choisi Akka car je savais que mes besoins pour le projet étaient de pouvoir répondre de manière efficace à des recherches Twitter et prendre des décisions en fonction de l’état de ma base. Étant donné que ces traitements sont enchaînés dans un pipeline, l’utilisation d’acteur m’est apparue comme naturelle. Chaque traitement pouvant être découpé en petites tâches élémentaires.
Twitter4j
Si vous ne connaissez pas Twitter, sortez de votre grotte. Si vous ne connaissez pas bien son fonctionnement, allez lire le manuel manquant de Twitter [en]. Toute cette expérience est partie de l’article de blog que j’avais lu et qui évoquait ce robot joueur sur Twitter, donc il me fallait un moyen de lui parler.
Twitter permet de facilement interagir avec son API pour accéder à toutes les fonctionnalités disponibles dans les clients Twitter classiques. L’authentification passe par de l’OAuth2. Et si vous ne savez pas comment ça marche, tant mieux !
Du coup, un de mes besoins était de trouver une bibliothèque qui me permettrait d’abstraire complètement toutes les communications avec Twitter. Très rapidement, mon choix s’est porté sur Twitter4j. Et de ce fait, mon choix de langage a aussi été validé (je t’avoue qu’au départ, je voulais faire ça en Rust, mais la seule bibliothèque Twitter que j’ai trouvée est pour le moins sibylline).
Envie de voir comment ce se passe en pratique ? Ça sera pour le prochain article…