Google Inbox

Immersion sous le capot

Arnaud Tournier, le 27-01-2015

Google Inbox

Présenté par Ray Cromwell.

Pourquoi Inbox ?

L’utilisation des email a beaucoup évolué depuis sa création. Par exemple de nombreuses personnes s’en servent comme liste de tâches (qui ne s’est jamais envoyé un email du type “N’oublie pas de faire XXX” ?).

GMail est déjà très puissant mais :

  • on utilise souvent ses emails comme todo list,
  • plus de 50% des personnes utilisent le mobile qui pose des problèmes de performances,
  • les emails sont compliqués, les utilisateurs préfèrent WhatsApp pour communiquer.

Les concepts fondamentaux d’Inbox

Les bundles

Remplacent les labels posés sur les dossiers. On peut les sweeper pour les marquer comme lu.

Highlights

Permet de voir les informations importantes contenues dans l’email sans même avoir à l’ouvrir. Celle-ci apparaît directement dans la liste des emails dans Inbox sous la forme d’une vignette.

Reconnait les informations et en fait un résumé suffisant.

Reminders

Pour fournir la fonction de pense-bête.

Si on donne un lien, il va être exploité.

Snooze

Permet de temporairement faire disparaître un élement. Celui-ci réapparaitra au moment voulu par l’utilisateur. Par exemple, snooze cet item jusqu’à ce soir…

Comment implémenter Inbox

Voilà donc les principaux concepts de l’application à mettre en oeuvre. L’application doit fonctionner sur le Web mais aussi sur les mobiles. On veut de l’iso fonctionnel sur toutes les plateformes. Le problème étant que chaque plateforme s’utilise avec son propre langage et son propre environnement. Ces langages sont de plus de natures différentes (JS, Java, ObjectiveC).

Et il est bien sûr exigé d’obtenir les meilleures performances tout en gardant un maximum de productivité.

On veut pouvoir itérer très rapidement au moment du développement de l’application.

On veut partager un maximum de code.

Première solution

On implémente trois fois la même application.

Facilite l’effet “Divergences de features” car chaque plateforme apporte ses spécificités.

Deuxième solution

On ne fait que du Web, même pour les mobiles.

Les performances ne sont pas encore là côté mobile…

Les émulations HTML5 des UI natives ne sont pas non plus parfaites. Il y a toujours un petit quelque chose qui ne va pas.

Troisième solution

C et C++ partout, compilé avec emscripten pour le Web, et natif pour les plateformes spécifiques…

Cela fonctionne, mais C/C++ est difficile à débugguer. Et on a plutot des developpeurs Java et/ou Javascript.

Quatrième solution

Tout écrire en Java : natif sur Android, GWT pour le Web, et J2ObjC pour iOS.

Problème : pas possible de faire levier sur les chaines de builds de chaque solution.

La voie du milieu

Utiliser le cloud ?

La logique métier est dans le cloud et les applications clientes font simplement des appels distants et ont une couche UI assez fine.

Problèmes :

  • Latence,
  • Pas de mode hors ligne,
  • Donc pas optimal pour l’utilisateur.

Par exemple pour Google Spreadsheet, le calcul des cellules était au départ déporté sur le serveur, provoquant de la latence. Aujourd’hui, cela est fait directement sur le client, et du coup c’est plus rapide, et cela fonctionne hors-ligne.

Le modèle hybride

  • L’UI est écrite dans le langage de la plateforme, en utilisant les chaines de build natives et le langage adapté à la plateforme ciblée.
  • On écrit un code partagé en Java pour la partie “logique applicative”.

Pour preuve, en prenant les test en compte, Inbox possède 60% à 70% du code partagé entre les différentes plateformes.

Comment cela fonctionne-t-il ?

Rendre les ninja JS heureux

  • GWT compile le Java vers Javascript,
  • JsInterop est utilisé pour exposer les classes Java au javascript,
  • Un linker spécialisé est utilisé pour générer les JsDoc de Closure (qui permettent aux développeurs Javascript d’utiliser correctements les API écrites en Java),
  • Le compilatuer Closure effectue les vérifications de typage et optimise le JS et le JS généré ensemble. (voir la présentation précédente avec la vérification du typage inter-langage). Closure fait également du pruning (dans les deux sens : code Java exposé mais pas utilisé, ou l’inverse).

Avantages

  • Crée un seul fichier Javascript,
  • Unification des API de logging (les mécanismes de logging de Java GWT et JS/Closure sont unifiés),
  • La gestion des exceptions Java fusionne avec le reporting d’error Closure, unifiant les stack trace,
  • La fusion des informations SourceMap provenant de Gwt et de Closure permettent le débuggage simultané du code Java et Javascript !!!
  • Closure Compiler “FileTypeHandler” + SuperDevMode pour éditer et rafraichir l’application en prenant en compte instantanément les changements des codes JS et Java.

Le processus de génération vers Objective C

  • Traduire Java en Objective C ave j2objc,
  • Importation des fichiers générés dans le projet XCode,
  • Faire quelques hack pour que cela fonctionne (cela montre que l’ensemble manque encore d’industrialisation…)

Mais !

  • j2objc supporte les compteurs de référence, Garbage collection et ARC,
  • De façon réaliste, iOS n’implémentera jamais de GC.

Exemple

com.sfeir.calc.CalcEngine

Pour Android

Du Java, on connait !!! La programmation est tout ce qu’il y a de plus classique.

Problèmes

  • Protobuf est utilisé. Mais la compilation en Java n’est pas optimale. A la place on peut utiliser protoc compliler pour générer pour chaque plateforme une version spécifique. Et ensuite on wrappe la representation native dans du Java.

  • Pour le débugging ? Printf fonctionne ! SourceMaps dans Chrome permet le débuggage au niveau du code Java avec en plus la deobfuscation des stack trace côté serveur.

Cas d’utilisation

Cette architecture n’est certainement pas adaptée à n’importe quelle problématique car elle apporte quand même certaines lourdeurs. Ray nous montre quelques critères favorisant l’adoption d’une telle architecture :

  • Quand on a des bibliothèques difficiles à réécrire, par exemple :
    • Transformations opérationnelles (Google Spreadsheets)
    • Calcul des formules (Google Spreadsheets)
    • Mécanisme de synchronisation,
    • Cryptographie, Codecs, etc.

Un projet “proof of concept” existe à cette adresse : https://github.com/Sfeir/jhybrid. Et oui, il s’agit bien de la société Sfeir qui héberge le projet !

Résumé

  • Ce qu’a fait Google n’est pas la seule façon de faire, mais cela marche plutot bien avec cette technique : Inbox et Spreadsheets sont plutot réussis.
  • On peut intégrer des équipes de developpement Java et Javascript, et faire travailler tout le monde ensemble.

Questions

Si le code Java à convertir a des threads ?

Ils ont déjà pensé à implémenter une émulation des threads avec les générateurs ES6. Mais rien de concret pour l’instant. Pour l’instant le risque technique est trop élevé.

Cela va-t-il sortir ?

Cela fait deux ans d’expérience, avec la construction de l’infrastructure qui va avec. Beaucoup de recherche, va et vient… Donc toujours à l’état de laboratoire. Ceci dit, Ray est prêt dit-il à assister quiconque voudrait démarrer un projet autour de ces principes, en le mentorant et en donnant des bouts de code.

Implémentation de Protobuf pour GWT ?

Oui il y en a, et pour le protocole Thrift (de Facebook je crois, ndlr) aussi. Mais en interne Google utilise sa propre tambouille.


Arnaud Tournier, le 27-01-2015