Groupon a commencé petit, avec une belle appli rails dans les règles de l'art. Mais leur codebase a rapidement explosé en même temps que la boite grossissait, c'est à dire, beaucoup et très vite. Ils ont du faire une appli mobile très rapidement et rajouter une couche d'API en facade de l'appli Rails. Puis ils ont racheté une boite qui faisait la même chose qu'eux mais pour la partie hors-US et se sont donc retrouvés avec deux fois le même set de features mais implémentées de deux manières différentes.
Bien sur, avec deux codebases différentes les features n'évoluaient pas de la même manière aux US que dans le reste du monde. De la même manière, faire évoluer l'appli mobile voulait dire faire évoluer le site principal. Avec autant de systèmes différents faire la moindre évolution mettait le système dans des états instables.
Ils avaient en cours un grand projet de modification du look and feel de leurs sites, mais réussir à propager celui-là partout en même temps était impossible. Certains utilisateurs voyaient le vieux Groupon, d'autre le nouveau.
Ils se sont donc mis dans un grand projet de refactoring de tout ça. Ils ont pris plusieurs mois pour tout refaire from scratch et... n'ont jamais réussi.
Ils ont alors pris une autre approche. Leur but était de découper l'appli principale en plusieurs petites applis. Ils ont commencé par extraire toute la procédure de signup dans un site externe, tout en utilisant l'API mobile.
L'appli de signup a été écrite en nodejs, et est toute petite, environ 15 fichiers en tout. Il y a eu quelques cafouillage lors de la mise en prod, mais rien de dramatique. Et surtout, vu que l'appli ne concerne que quelques pages, les problèmes étaient assez localisés.
Finalement cette première expérience porte ses fruits, ils veulent le faire sur une autre partie. Ils demandent alors à une autre équipe de réecrire une autre feature avec la même stack technique, histoire de tester si les choix techniques sont cohérents. Cette fois-ci, la modification a été plus longue, 6 mois au lieu de 2 semaines, car elle nécessitait des modifications de l'API qui à leur tour demandaient de la modification du legacy.
Après cette étape, ils passent à la vitesse supérieur et entament plusieurs chantiers en parallele. Chacun d'eux prends une feature et la transforme en une appli nodejs. Plusieurs équipes, à plusieurs endroits du monde, travaillent avec la même stack. Ils en profitent pour mettre au point un framework interne pour simplifier la cohérence des devs et créer la documentation qui va avec.
Là, ils décident de revoir le CSS et de faire un bootstrap-like interne pour que le look and feel de toutes les pages soit cohérent. Il est assez facile de mutualiser une feuille de style, mais il était plus dur de garder une cohérence en terme de mise en page quand plusieurs équipes, plusieurs designers font leurs pages chacun de leur coté.
Ils optent pour une modularité sous forme de components. Chaque équipe écrit des components (html/css/js) qui peuvent être inclus dans des pages et un serveur central abrite la liste des différents templates de page existants, dans lesquels ils peuvent inclure leurs components. Cette méthode leur permet de garder une cohérence dans les différentes pages, tout en laissant un peu de liberté aux designers pour ne pas être toujours bloqués dans les mêmes templates.
Ils testent plusieurs méthodes pour assembler les templates avec les components, et finalement parviennent à une solution à base de templating mustache et de chargement des components coté client en javascript.
Une fois que leurs chantiers parallele ont fonctionnés, ils ont bloqué la production pendant 2 mois (sauf pour les bugfix) afin de finir de casser l'appli rail originale en apps nodejs. Ca leur a pris plus de temps que prévu car ils avaient plus de pages qu'ils ne le pensaient.
Concernant l'API, ils ont du garder une extreme retro-compatibilité car des tas d'applis externes en dépendent. Néanmoins ils ont développé une couche d'abstraction qui prends les anciennes urls en entrée et les passent à la nouvelle API. Ils monitorent l'usage de chacune des anciennes urls et les enlevent au fur et à mesure qu'elles ne sont plus utilisées.
Un side effect bonus qu'ils ont découvert avec cette manière de splitter en plein de petites applications c'est qu'il leur est alors très facile de faire une feature spécialisée pour certains pays qui sont culturellement très différents. Ce n'est de toutes façons qu'une quinzaine de fichiers, qui prennent environ 2 semaines à développer. Si une app prends plus de 2 semaines, c'est qu'elle est trop grosse, et il faut alors la splitter.
Take-away : - Inutile de reprendre un monolithe from scratch - Trop dur de tout découper en une fois - Isoler une feature atomique, la refaire à part - Tester si marche pour une autre feature, avec une autre team - Itérer au fur et à mesure que la confiance vient - Assurer la rétrocompatibilité de l'API - Mesure pour enlever ce qui ne sert pas au bout d'un moment.
Tools and techniques for managing complexity at Etsy
Encore Etsy, et leurs méthodes magiques. Cette fois, le talk était accès sur leur manière de scaler (aussi bien en terme d'utilisateur, de taille de la codebase, ou de taille de leur équipe).
Tout d'abord, ils axent tout sur le partage. Partage en open-source de leurs outils, partage des dashboard ou des logs accessibles à tout le monde, employés qui changent d'équipe pour 1 mois chaque année.
Ensuite, ils déploient régulièrement, et font de petits commits. Chaque changement est donc assez peu impactant, et c'est donc plus facile de corriger ou de changer de trajectoire.
"You write it, you run it". Chacun est responsable de deployer la feature sur laquelle il a travaillé, de mettre en place les dashboards pour monitorer.
Vu qu'ils font de la feature flipping à mort, et qu'ils ont près de 300 "pages" principales différentes sur leur site (sans parler des version admin, identifié, membre, vendeur), ils ont calculé avoir approximativement 1.200.000 pages possibles différentes.
Avec le temps, le nombre de CSS et de JS augmente considérablement et ils ne savaient pas comment trouver du code CSS mort dans leur application. La méthode manuelle était de chercher un selecteur, trouver dans quel fichier il était défini, trouver tous les fichiers qui @import ce css, puis les templates html qui incluent ce css, et les template qui incluent le template, pour remonter aux fichiers PHP puis aux règles apache... Bref, impossible à maintenir.
Ils n'osent pas supprimer du code sans savoir les impacts. Mais garder du code mort ça fait de l'overhead, aussi bien mental pour le développeur, que pour le cpu lors de la compilation ou le réseau.
Ils ont donc construit un outil nommé Shrinkray qui tourne en live dans le navigateur des visiteurs. Il va prendre 10 selecteurs CSS au hasard dans les feuilles de style chargées, et regarder si elles matchent quelque chose sur la page en question. Ces informations sont ensuite envoyées au serveur d'Etsy qui aggrège des stats là dessus qu'ils peuvent consulter et ainsi isoler le "vrai" code mort.
Pour eux, le browser du client fait partie intégrante de leur architecture et ils l'utilisent comme cela.
Maneuverable architecture
Notre speaker nous a parlé de James Boyd, un pilote d'avion de combat durant la guerre qui avait une manière de piloter très spéciale et peu commune. Il ne voulait pas l'avion qui va le plus vite ou le plus haut, mais celui qui peut plus facilement tourner.
La métaphore porte sur le fait que "sans maitrise, la puissance n'est rien". L'idée est qu'il est très important de pouvoir réagir vite aux inputs exterieurs et que cela peut donner un avantage important sur les concurrents.
Il enchaine sur le fait que la meilleure manière de pouvoir manoeuvrer rapidement est de ne pas avoir une appli monolithique mais une multitude de petites applis qui peuvent être maneuvrées independemment.
Pour évoluer rapidement, ne pas se focaliser sur les détails. Pas la peine d'avoir une api avec des endpoints super bien mappés. Urls are cheap. On peut en créer plein pour s'adapter aux différents besoins même si plusieurs urls pointent au même endroit. Il suffit d'avoir des logs sur les utilisation des urls pour savoir quand on peut en dégager une du code si elle n'est plus utilisée.
Pour gérer les différences de pays (i18n, différences légales et culturelles), ils ont une liste de components visuels d'UI générique, tweaking par une liste de features flippés du moment qu'une est nécessaire pour un cas précis, sa spécificité est ajoutée à la liste des options flippables pour tout le monde.
Ils versionnent leurs components, et laissent toutes les versions dispos en ligne en même temps. Comme ça, chaque site de leur portail peuvent utiliser la dernière version d'un component lors de leur conception et ne pas avoir besoin de gérer l'upgrade du component central automatiquement, c'est du opt-in quand ils veulent uploader il leur suffit de changer l'url.
Il utilise les URL pour absolument tout, des fichiers statiques jusqu'au versionning de ses FAQ, toutes les versions de tout ce qui est versionné est toujours disponible sur leur réseau à tout moment. Ainsi chaque objet possède un identifiant unique et un nom pointe toujours vers exactement la même chose immutable.
Il pousse le "vice" plus loin, en donnant par exemple le cas des paniers des sites d'e-commerce. Chaque panier est unique, avec un certain identifiant. Plutot que d'avoir un panier personel lié à un utilisateur, il a une liste de paniers, chacun avec un identifiant unique et une combinaison d'articles dedans, ainsi chaque utilisateur possède seulement une référence vers un panier. Cela permet d'avoir des objets complétement différents, indépendants.
Il donne ensuite un exemple de comment il a découplé un système d'envoi de mail de rappel d'expiration de carte bleu en plusieurs systèmes : un qui register des taches CRON à une certaine date et une certaine URL, un autre qui prends une date et retourne une date interessante pour envoyer un mail (genre pas le week-end) et finalement un autre service qui envoie le mail.
Globalement son idée est bien foutue et fonctionne globalement comme un pipe, avec une vraie separation of concerns. Malheureusement, ça peut facilement être mal fait et partir dans trop de couches d'abstraction qui rendent le système difficile à comprendre et maintenir.
Hoodie, Offline first
Hood.ie est un framework dont le but est de faciliter le mode offline. L'idée est que nos devices mobiles ne sont pas toujours connectés, il y aura toujours des métros, des tunnels, des zones non-connectées. On passe sans cesse d'un mode connecté à un mode non-connecté.
Pour hood.ie, l'appli est pensée pour être offline, l'online est une feature. Dans les applis d'aujourd'hui, le mode offline n'est pas toujours pensé, on a des spinners qui tournent indéfiniment pour rien.
On peut utiliser le cache manifest des browser pour définir les objets qui doivent être gardés en offline et ne doivent pas etre cherchés online. Le système possède encore pas mal de problèmes qui le rendent difficile à utiliser.
Par la nature même du cache manifest, il est difficile de mettre à jour les éléments qu'il cache. Il faut mettre à jour le cache manifest lui-même (par exemple en ajoutant un commentaire de timestamp). Même si l'appli est actuellement connectée, le cache manifest ira toujours chercher ses données en offline. Et si on est offline, un asset qui n'est pas défini dans le manifest (même s'il est en cache), ne sera pas affiché. Tout ça sans parler qu'il faut recharger deux fois le manifest pour que sa mise à jour soit prise en compte.
Autre solution, il y a les serviceWorkers qui commencent à arriver, qui permettent de se plugguer sur les events du navigateur, pour par exemple accrocher un event fetch pour télécharger une ressource externe et ainsi implémenter sa propre logique de cache.
La définition même de "online" est douteuse. Est-ce que ça veut dire connecté à un réseau wifi ? 3G ? Quid des proxy, ou des limitations de forfait data ? Et si c'est juste le serveur et/ou la ressource en question que je souhaite contacter qui est inaccessible ?
Sous Firefox et IE par exemple, il existe un event pour savoir si on passe en offline ou non, sauf qu'il est fired quand on passe manuellement le browser en mode offline. Chose que personne ne fait jamais.
Il existe un workaround qui consiste à se plugguer sur toutes les requetes AJAX de son appli et de capter les timeout et de passer alors l'appli en mode offline. A partir de ce moment, on arrete de faire des requetes, on tente juste, régulièrement, de poller le serveur pour voir s'il est à nouveau accessible et repasser en mode online.
Il faut bien que je garde mes données en local quand je suis offline. On peut bien sur mettre ça dans un cookie, mais c'est une extremement mauvaise idée car il y a une limite à la quantité de data qu'on peut y mettre et surtout, les cookies sont renvoyés au serveur à chaque requete.
Il y a localStorage et son API simple à base de setItem(key, value) et getItem(key). C'est simple, ça marche partout. Mais c'est synchrone, et ça bloque mon UI quand je m'en sers, et ça se remarque vite quand je traite de grosses data. Et puis surtout, ça ne peut stocker que des strings, donc obligé de convertir en JSON et parser à chaque fois. Sans parler de la limite de taille, d'environ 5Mo, et qu'il n'y a aucun moyen de savoir si on a dépassé ou non la limite.
Maintenant, on a indexDB, qui est asynchrone, et qui fait des transaction atomiques. En plus on peut stocker des objets directement et la limite de taille est bien plus grande (~50Mo). L'API est plus complexe, et les implémentations sont différentes selon les browsers.
La solution est d'utiliser localForage, un wrapper développé par Mozilla qui permet d'utiliser indexDB avec la syntaxe simple de localStorage, tout en gérant les fallbacks.
Hood.ie est parti sur du CouchDB, car il propose une très bonne synchronisation master/master, ce qui est parfait pour une synchronisation entre un client et un serveur qui sont tous les deux sources de données principales.
Avec Hood.ie, chaque utilisateur possède sa propre base de donnée CouchDB, donc la synchronisation se fait vraiment entre deux objets qui sont liés à un unique utilisateur. Parfois des objets sont partagés entre plusieurs nœuds serveur, et dans ce cas c'est le serveur qui se charge de faire la synchro entre les nœuds (copier les nouvelles versions des objets dans les bases de chacun), les bases sont ensuite synchronisés avec les clients.
L'idée principale pour la synchro est d'avoir la même schéma de stockage en local et sur le serveur, avec un protocole particulier qui permet de faire la synchro. Au dela de PouchDB/CouchDB, il existe aussi JsGit, qui permet d'implémenter le protocole git pour versionner ses données et les pusher/puller avec un serveur.
Au niveau de la sécurité, aucune vérification n'est faite pour les modifs en local, c'est seulement une fois qu'on effectue la synchronisation que le serveur vérifie l'authentification.
Comment gérer les conflits ? En fait, il faut les éviter. L'idée est d'avoir plein d'objets (documents) différents plutot que de gros objets pour éviter et simplifier les conflits. Par exemple , si on souhaite gérer un blog avec ses posts et les commentaires associés, il vaut mieux avoir un objet pour le post, et un autre pour la liste des commentaires, sinon deux utilisateurs peuvent poster un commentaire en même temps et avoir un conflit sur le post.
Il est très important de montrer à l'utilisateur que les données sont accessibles, il faut éviter au maximum de cliquer sur quelque chose et d'avoir un spinner infini qui apparait.
Il faut aussi que ce soit transparent, il ne faut pas que l'utilisateur ait besoin de faire des actions spécifiques pour enregistrer quelque chose pour l'offline (exemple typique, les FAQ/Docs qui sont souvent fetchées depuis le site web dans une app).
Garder un maximum de choses en localStorage, pour accelerer les calculs et rendre l'UI smooth. Si besoin de fetcher quelque chose, le faire en tache de fond, quand l'utilisateur ne le voit pas.
Attention, mettre ses données dans les mains de l'utilisateur en local fait repenser l'architecture en terme de sécurité des données.
Mobile webperfs : Getting and Staying fast
Le mobile devient de plus en plus important, le nombre de sociétés qui possèdent désormais plus de visiteurs en mobile qu'en Desktop ne cesse d'augmenter. Le mobile est devenu un first class citizen, et il faut en prendre soin.
On s'attends à ce qu'un site soit aussi rapide sur mobile que sur desktop, voir plus. On se repose sur le fait que les téléphones sont de plus en plus rapides, ont de plus en plus de RAM, qu'on passe de EDGE à la 3G, puis la 4G.
Mais la 4G n'est pas la solution ultime. Il y aura encore plus rapide dans le futur, et tout le monde n'aura pas la même connection. Il y a aujourd'hui plus de cartes SIM en circulation au Royaume-Uni que d'habitants. Ajoutons à cela la diversité des devices, et on a un panel extremement large et on ne peut pas se contenter de développer pour le haut du panier en terme de vitesse.
La latence est le principal problème pour la performance en situation de mobilité. Même dans une situation parfaite, avec de la fibre optique, la data est limitée par la vitesse de la lumière, un round-trip jusqu'à un serveur à l'autre bout du globe ne pourra jamais dépasser la vitesse de la lumière, ou plus pragmatiquement les 2/3 de la vitesse de la lumière avec nos infrastructures actuelles.
Niveau mobile, la 4G améliore la latence par rapport à la 3G, mais un bottleneck se créé au niveau des fournisseurs d'accès. Plus il y a de personne sur le réseau 3G, plus la vitesse de download est dégradée pour chacun. La latence est aggravée en situation mobile du fait du protocole employé par la 3G. Le fournisseur d'accès régule la latence réseau sur son propre réseau, et pas au niveau du device, il peut donc se passer une à deux secondes avant qu'une requete envoyée par un téléphone ne parte réellement de celui-ci.
Rajoutons à tout cela que TCP n'est pas adapté à une multitude de petits fichiers, et que les réseaux wifis généralement accessible en situation de mobilité (Starbucks, conference room) sont rarement au top, on a un panel de situation de surf sur mobile qui est assez noir.
La grande question est donc : comment est-ce qu'on mesure les performances web dans ces conditions ?
Heureusement, on commence à avoir des outils assez évolués pour regarder pas à pas le chargement de notre page et repérer les problèmes. Les browsers (modernes) implementent désormais la navigation API ou la Resource Timing API qui donnent beaucoup de metrics sur les différentes étapes de rendering de la page depuis les premières connection réseau jusqu'à la première intéraction utilisateur possible en passant par les différentes phases de rendering. Une plateforme comme NewRelic permet même de visualiser tout cela en mode Saas.
Le bon vieux WebPageTest reste encore l'outil priviliégié pour visualiser le chargement de tous les assets d'une page en mode waterfall, incluant le temps de résolution DNS, de connection, de traitement serveur et de téléchargement. Les bottlenecks sont alors extremement facile à repérer et les optimisations sautent au yeux. Le site webpagetest.org permet de faire des tests sur son site depuis différents endroits du globe avec des qualité de connection variées.
Dans le même genre, Appurify se concentre sur la connection mobile. Leurs serveurs de tests se situent à San Francisco mais ils ont moyen de simuler la qualité d'une connection mobile sur par exemple du Vodafone UK, avec la possibilité de choisir la qualité de réception d'une à cinq barres, ou de simuler un réseau moisi comme celui offert par un Starbucks en periode d'affluence.
Pour tester en situation réelle, les Chrome DevTools permettent de brancher son Android sur son laptop et de le controler depuis celui-ci. Il est ainsi possible d'y brancher la console de debug de chrome et d'étudier le comportement du chargement des pages.
A noter aussi qu'un outil comme Charles peut s'insérer en tant que proxy entre le device mobile et le réseau wifi sur lequel il se connecte et peut ajouter de la latence à la demande pour simuler un réseau mobile.
S'en sont suivis des exemples de quelques sites de "gros" acteurs qui prennent un temps monstrueux à se charger sur mobile, comme nbcnews et ses 19s de chargement, 344 assets sur 115 domaines différents.
Et donc, dans tout ça, quelles sont les solutions ?
La solution la plus facile est déjà tout simplement de réduire la taille de la page. L'objectif est d'avoir une page, assets compris, qui pèse moins de 300Ko. pour ça, on passe par du Gzip qui est un gain instantané sur tous les assets textes (js, css, html). En quelques lignes de config serveur on peut déjà gagner près de 80%.
Pour réduire la taille des images il existe pas mal d'outils d'optimisation. Une simple passe d'ImageOptim sur un fichier jpg permet en général de gagner 50% de taille de fichier sans que la différence sur l'image ne soit perceptible par un œil humain. Les choses se compliquent quand on souhaite prendre en compte les problématiques de responsive webdesign, mais le sujet pourrait avoir sa propre conférence tellement il est complexe.
D'autres amélioration qui peuvent etre faites sur les images sont d'utiliser SVG quand cela est possible, ou des iconfont. Il est souvent aussi possible d'utiliser du CSS plutot qu'une image de fond (pas toujours, certains dégradés demandent plus de travail par le browser que le simple affichage d'une image).
Enfin, il faut faire attention quand on charge des webfonts, il y a de nombreuses façons de le faire mal et de charger trop de fonts non-utilisées, ou devoir attendre l'execution d'un script. Il est à noter que l'utilisation de webfont est à double tranchant : tant que la font n'est pas chargée, aucun texte n'est lisible. Certaines fonts sont très lourd à charger car elle contiennent les glyphes d'alphabets dont vous n'aurez jamais besoin (cyrillique, grec, etc). Réduire la font au subset des glyphs qui vous interesse permet de gagner en général près de 33% sur la taille du fichier
Ce qui me permet d'enchainer sur le second point d'amélioration principal : diminuer le nombre de requetes. Le protocole HTTP est fait de telle manière qu'il y à l'initialisation une congestion window qui force le browser à effectuer plusieurs round-trip avant de pouvoir faire son téléchargement à vitesse maximale. Les détails de cette partie restent encore un peu flou pour moi (HTTP ? TCP ? où se situe le bottleneck ?). Mais cela signifie qu'il existe un sweet spot, une taille de fichier maximale que le client peut télécharger en un seul round-trip. Il y a moyen de configurer cette valeur (initcwnd) sur son serveur assez facilement. La valeur par défaut est généralement à 3, et a majorité des CDN le montent à 10, il est donc recommandé de mettre soi-même cette valeur à 10 pour en profiter.
Une fois que tout ceci est fait, il faut tirer partie du cache. La règle d'or est : Cache all the things. Que ce soit coté serveur ou coté client, il ne faut pas hésiter à cacher un maximum de choses pour éviter les requetes réseaux.
Enfin, une fois qu'on est arrivé là, que nos assets sont bien arrivés dans notre client, le dernier point que l'on peut optimiser est le rendering. Certains élements de notre page bloquent le rendering, c'est à dire que rien ne va s'afficher tant qu'ils ne se sont pas executés. Le javascript est le premier sur la liste, c'est pour ça qu'on recommande de mettre les scripts en fin de page et d'attendre le body.onload pour initier leur traitement. Mais comme je disais au dessus, il y a aussi les fonts, qui empechent l'affichage du texte sur lequel elles sont définies tant que le fichier de font n'est pas chargé.
Si vous avez bien tout réalisé jusqu'ici, votre page a du se charger plutot bien. Mais maintenant, votre utilisateur va changer de page et... tout ce processus va recommencer à zéro ? bien sur, avec un bon cache, pas mal de choses seront déjà là, mais il existe quelques autres astuces qui permettent d'anticiper les changements de pages. Les browsers commencent à mettre à disposition du developpeurs des outils comme dns-prefetch, subresource, prefetch et prerender qui permettent de donner des indices au browser sur ce que l'on pense que la prochaine action de l'utilisateur va etre, pour que lui puisse mieux organiser de son coté les ressources qu'il va charger.
Si on prends un peu de recul sur le coté technique, il y a encore des astuces qui permettent d'améliorer non pas la vitesse de chargement de votre page mais la perception qu'en ont les utilisateurs.
Déjà, si vous faites comme le Guardian, vous chargez en premier le contenu de votre page, ce pour quoi vos utilisateurs viennent (le titre et le texte de l'article par exemple), puis vous chargez la mise en forme, en seulement en dernier le reste (analytics, pubs, boutons de partage). Vous pouvez aussi jouer avec le fold, et ne charger que ce que l'utilisateur voit réellement sur son écran, et ne charger le reste (commentaires, etc) que s'il scroll.
Le site mobile d'Instagram va même plus loin, en trichant sur le feedback visuel. Dès que vous cliquez sur un bouton, il change d'aspect pour indiquer que l'action a réussie, même la requete n'est même pas encore partie au serveur. De la même manière, ils commencent à uploader la photo que vous venez de prendre pendant que vous écrivez son commentaire, comme ça, dès que vous appuyez sur Send, ça semble instantané.
Et finalement, comme le disent si bien les Animaniacs : "If in life you don't succeed, blame it on your parents". C'est ce qu'à fait Facebook. Ils ont utilisé le spinner du téléphone plutot que leur spinner custom car leurs tests montrent que comme ça les utilisateurs pensent que c'est la faute du téléphone et pas la faute de l'appli.
En quelques lignes, le take-away de tout ça : - Measure. Measure. - Send less bytes - Prioritise what you send - Send it when no-one is looking - If else fails, distract the visitor
Continuous Improvement Version Constant Innovation
Basically there are two main issues with Continuous Improvement. Continuous and Improvement
L'amélioration n'est pas assez. Blackberry améliore depuis des années mais son produit reste globalement le même. L'amélioration n'est pas l'innovation, cf. iPhone.
Ca part d'un postulat négatif, sentiment que de toutes façons ça ne sera pas assez bien, alors on rentre ensuite dans l'apathie, du "à quoi bon ?"
Il y a une limite à l'amélioration continue. Un coureur de marathon ne pourra plus s'améliorer à un certain moment. Ca ne scale pas.
Qui décide de ce qui doit etre amélioré ? Users ? La presse ? On entre dans du CDD (Complaint Driven Development) ou du PRDD (Press Release Driven Development)
Il est impossible de s'améliorer constamment, le mouvement perpétuel n'existe pas, on tends vers une limite.
A un moment, il vaut mieux arreter d'améliorer et partir sur un autre projet.
Il ne faut pas se fixer des objectifs, surtout en tech où tout évolue trop vite. Il faut se fixer des directions dans laquelle on veut évoluer. Le probleme d'un objectif est qu'on ne pourra peut-être pas l'atteindre, même s'il n'a plus de valeur à un instant t+1, mais qu'on continuera de se fatiguer à tout faire pour l'atteindre.
Voir la suite du talk directement en vidéo (plus de batterie pour prendre des notes).
J'ai découvert la QCon en allant à la QCon London 2014. En plus d'un cadre fantastique en plein cœur de Londres, on a eu le droit à des conférences passionantes. Je n'ai pas fait de compte-rendu des keynotes, qui étaient plus de l'entertainment (à la TED) et qui méritent plus d'être vues en vidéos que racontées à l'écrit.
Je retiendrai surtout de cette QCon la qualité de l'outillage d'Etsy et le niveau d'excellence qu'ils ont.
How outages shaped Etsy's architecture
Après chaque problème en prod chez Etsy, ils font des post-mortem publics. Tout le monde est invité à venir voir pourquoi ça a planté, et comment on fait pour éviter que ça se reproduise. Tous les post-mortem sont "no blame", si quelqu'un a été assez confiant pour pusher en prod et que ça a planté, c'est que le système ne possède pas assez de vérifications, il faut donc améliorer le système plutot que de pointer quelqu'un du doigt.
Ils ont même un outil (open-source) nommé morgue qui permet d'historiser les fails et de voir leur fréquence, ceux qui reviennent souvent, ceux qui ont des causes communes, etc.
Leur motto est que "There is no such thing as human error when building resilient systems". Ca veut dire que si on veut un système qui résiste aux erreurs, et bien il faut des erreurs pour pouvoir s'y adapter.
Parmis les solutions qu'ils donnent pour réussir à éviter et/ou plus facilement se relever d'une erreurs :
Les équipes doivent connaitre le code des autres équipes. Il est très difficile de trouver une erreur avant qu'elle n'arrive en prod si chacun ne regarde que le code de sa team.
Ils releasent en open-source tout ce qu'ils font qui peut aider. Ca permet de rendre aux autres ce qu'ils ont appris de l'open-source et permet d'améliorer leurs outils.
Ils ont une batterie de test avant la mise en prod, et des code reviews. Néanmoins certaines choses peuvent quand même peter en ligne, comme par exemple une modification de code qui est impactée par une modif de l'archi (exemple d'un script qui s'attendait à remplir la mémoire de 4Go mais qui a rempli la mémoire upgradée de 32Go).
La suite de la prod était une suite de leurs fails en prod, mais c'était très spécifique à leur config et peu utilisable tel quel :
Ils avaient un sharding de couples master/master en mysql, plus un serveur global mysql qui contient leur dbIndex pour retrouver le noeud du shard en fonction de l'id de l'objet. Mais ils ont aussi utilisé ce même serveur pour garder leurs logs, qui à cause d'un incident en prod ont explosés, qui ont tué le serveur et re-fait péter la prod.
Ils ont eu un tweet-pocalypse aussi en ayant utilisé toute la place nécessaire pour les int à cause d'un auto-increment.
Development, Deployment and Collaboration at Etsy
Etsy est construit sur une stack LAMP classique, avec un Master/Slave MySQL. Le tout dans une app monolithique, qui comporte à la fois le site public et leur interface d'admin. Néanmoins, ils parviennent à déployer tout ça environ 50 fois par jour.
Ils emploient abondamment le feature flipping. Ils ont en fait un énorme fichier de config PHP qui contient la totalité de leurs configs, et il est interdit de déployer quelque chose qui modifie à la fois le code et la config. Dans leur process, ils poussent régulièrement du code en cours de conception sur la prod, mais qui n'est pas forcément activé, et ils l'activent petit à petit à une certaine partie de leurs utilisateurs, progressivement, en gardant les deux versions en parallelle jusqu'à ce que la nouvelle est été déployée à toute la population, et à ce moment seulement ils enlevent l'ancienne version de la code base.
Chaque développeur possède une VM avec les recettes Chef qui vont bien pour déployer en local une copie conforme du site. Même OS, même version de php, même config. Seule la base de donnée est réduite. Comme ça chaque dev peut voir l'impact de son code sur la totalité de la stack et l'excuse "Works for me" ne marche plus.
Ils ont aussi un outil en interne qui permet de télécharger des VM pré-configurés de différents tailles (il est parfois nécessaire de faire des tests avec une plus grosse db, avec plus d'images, etc).
Ils utilisent une batterie de Jenkins (~400) en parallelle pour executer leurs tests. Ceux-ci sont installés dans des containers LXC, répartis sur trois disques SSD. Certains builds Jenkins sont marqués comme heavy et seulement un build heavy peut être executé sur un SSD à la fois, les autres sont executés en parallelle du moment qu'il reste des resources.
Ils possèdent aussi un environnement nommé Princess qui est une copie à l'identique du site de prod, avec exactement la même config, même serveur, même database, mais qui n'est accessible qu'en interne. C'est sur cette version que les tests d'intégration sont executés. Si ça passe sur Princess, ça passera en prod.
Ils utilisent aussi un outil nommé "try" qui va créer un patch de leur branche actuelle, l'appliquer sur la branche master, lancer la batterie de tests et reporter le résultat. Ca leur permet de lancer leur batterie de tests sans pourrir l'Intégration Continue.
Le déploiement chez Etsy n'est pas sale, ni compliqué, et ne fait pas peur. Tous les nouveaux développeurs sont invités à déployer dès leur premier jour, grâce à leur outil interne nommé Deployinator. Il permet de déployer en un clic, indique l'historique des déploiement passés ainsi que la version actuellement déployé sur chaque environnement.
Ils ont un dashboard qui affiche des graphs sur plein de choses, beaucoup de choses. A la question "Should I graph that ?", la réponse est toujours Yes. L'outil est accessible à tout Etsy et indique par exemple le nombre de login, logout, inscriptions, paiement, erreurs 404, etc. Si une courbe devient anormale, ça veut dire que quelque chose ne se passe pas normalement.
La totalité des logs de tous leurs serveurs sont agrégés et streamés sous forme d'appli web (Supergrep++), accessible à tous, avec possibilité de filtrer les logs. Un autre outil similaire, Supertop, est aussi accessible.
Chaque année, ils félicitent le dev qui a pété la prod de la manière la plus originale possible. Ils ont par exemple explosé la mémoire disponible sur leurs serveurs simplement en supprimant un fichier CSS. Il s'avère qu'il était utilisé sur la page d'erreur, qui le chargeait, qui donc chargeait la page d'erreur, qui chargeait le css, etc. Ce genre de bug montre que le système n'est pas complétement maitrisé et qu'il y a moyen de s'améliorer.
Ils font des Post-Mortem après les urgences en prod, où tout le monde peut venir, et où le motto est "No Blaming". La question est "Pourquoi la personne qui a pushé pensait que ça n'allait rien péter ?". L'outil ne doit pas permettre de pousser quelque chose qui va peter, si ça a été possible, il faut donc améliorer l'outil, pas punir les gens.
Il n'y a pas que les ops qui peuvent etre d'atsreinte. Ils ont des équipes d'astreinte pour les devs, le payment, le support aussi. Chacun est d'astreinte une semaine toutes les 4 semaines. Ca veut dire en cas de prob sur la prod, s'en occuper en priorité (en moyenne 1 ou 2 probs par semaine).
Si le probleme a lieu juste après un deploy, on appelle un dev car c'est sans doute lié à du code pushé. Si c'est à un autre moment, on appelle un ops.
Il est interdit de déployer avant 7AM ou après 10PM.
De la même manière qu'on utilise les mailing list interne à Octo, ils ont une centaine de channels irc, sur différents sujets. Ca leur permet de coordonner facilement les choses au travers de l'entreprise sur un sujet donné.
Par exemple, leur channel #warroom est là où tout le monde va en cas de problème majeur sur le site. Le topic indique la source des problème et est mis à jour dès qu'une nouvelle info est trouvée, de manière à ce que chacun puisse être tenu au courant des soucis. C'est plus facile pour se coordonner, partager l'information, etc.
Chaque semaine, ils font un BBL (pizza payée par Etsy) où un membre de la boite présente une partie sur laquelle il travaille (pas forcément du code, peut etre paiment, support, etc) pour que tout le monde ai une vue d'ensemble.
Chacun est encouragé à visiter les datacenters, à s'inscrire comme "touriste" sur l'astreinte (pour voir à quoi ressemble un probleme en prod quand ça arrive, mais sans avoir besoin d'aller le corriger).
Après un 1 an à Etsy, on devient un Senior, et on doit alors passer 1 mois par an dans une équipe complétement différente de la sienne.
How you can trust crypto
Rappel de quelques fondamentaux en crypto. Ou plutot de dire que la crypto c'est très difficile et qu'il faut vraiment etre un expert pour savoir ce que l'on fait, et que c'est très facile de faire n'importe quoi.
C'est toujours un compromis entre le rêve du cryptographe et le real world, l'équilibre à trouver entre sécurity et convenience.
Il faut bien faire la différence etre les algorithmes de crypto qui existent, mathématiquement, et leurs implémentations dans les différentes librairies des différents langages.
Les librairies propriétaires en closed sources sont déjà très dangereuses, à éviter complétement, mais les libraires open-sources ne sont pas forcément mieux (cf. les 10 millions de $ payés par la NSA à RSA pour laisser par défaut un random generator possèdent une backdoor).
Une bonne API doit avoir des paramètres par défaut qui sont sains. Facile à faire les choses bien, difficile de faire n'importe quoi. Ne doit pas utiliser les vieilles méthodes (legacy) qui avaient une limite sur la taille des clés à cause d'une législation américaine.
PKCS#11 est trop vieux, limite sur la taille des clés. SHA1 est trop faible. Et la spec est trop lache, trop de détails sont laissés et les implémentations sont toutes différentes.
Attention à OpenSSL, qui est un projet initié par un gars initialement pour apprendre. Le code source contient encore une 40aine de TODO/FIXME.
W3C a proposé une crypto API, qui partait sur de bonnes bases, mais qui à cause du support de SSL legacy a été obligé de permettre des clés faibles. Néanmoins, les defaults sont bons.
NaCl utilise des primitives qui semblent très robustes, créé par Dan Berstein. Le soucis est qu'il n'y a pas assez de reviews officielles, scientifiques dessus, donc difficile de savoir si c'est vraiment robuste.
Eviter les implémentations mathématiquement trop peu connues, car l'intéropérabilité va etre un cauchemar.
Le quantique n'est pas la solution pour la crypto dans le futur car il n'y a actuellement que 3-4 personnes au monde qui sont capables de comprendre la crypto quantique, c'est donc assez dangereux de faire confiance sur un sujet aussi important uniquement à une poignée de personnes.
Pour finir, "Security is fractal", on peut se pencher sur n'importe quelle partie de la sécurité et trouver des challenges énormes aussi important que ceux de la big picture.
En quelques mots : - Open and not Proprietary - Avoid legacy - Check out common pitfalls - Review by others
BladeRunnerJS
Les gars de BladeRunnerJs travaillent sur une grosse application front de trading. Ils ont une énorme codebase, plein de développeurs, dans différents pays, depuis plusieurs années et ils ont bien sur du mal à maintenir tout ça.
Ils ont donc des besoins de structure du code, facilité à trouver les fichiers responsables d'une feature, besoin d'avoir une UI cohérente sur l'ensemble des features. Ils ont aussi besoin qu'il soit facile pour de nouveaux arrivants de comprendre le code, et pour d'anciens de contribuer sur d'autres parties.
Ils résolvent cela grâce à des guidelines de code communes, et pour que chacun puisse lancer la totalité de l'appli, ils ont des mocks de chaque partie. (pour le coup, c'est une approche complétement contraire à Etsy qui instancie une copie-conforme du site de prod dans une VM pour chaque developpeur).
Jusque là, leurs problèmes sont normaux, et on a les mêmes. Mais ils ont mis en place leur propre solution, nommée BladeRunnerJs.
C'est un ensemble de conventions de nommages et un serveur nodeJS qui tourne par dessus pour pouvoir lancer leur appli en mockant chaque component qui n'est pas utilisé.
Globalement leur solution est bien pensée et réponds sans doute à leur besoin, mais elle est en version 0.4 et si on veut l'utiliser il faut se plier à des tas de leurs conventions qui marchent bien dans leur framework mais qui rendent les fichiers inutilisables à l'exterieur. Au final, pas convaincu.
Library front qui permet d'écrire du code de type node et de l'utiliser dans le browser. Ca passe par un compilateur qui transforme le code original pour qu'il tourne correctement.
On peut donc utiliser require() et les modules node (depuis npm ou directement depuis le core). Du coup, comme c'est une commande de build, on peut l'include dans du grunt et/ou du jenkins.
$ browserify index.js -o build/build.js
L'avantage n'est pas tant d'utiliser des modules node dans le browser, mais de pouvoir utiliser la modularité que permet la syntaxe require/module.exports.
CasperJS
Présentation de Mickael Andrieu de SensoLab (spécialisé PHP)
CasperJs est un outil basé sur PhantomJs, spécialisé dans les tests fonctionnels, mais qui permet d'autres choses.
PhantomJS est un webkit headless, il permet donc de simuler le comportement de Safari, Chrome/Chromium et Opera (à quelques différences près). Il existe aussi SlimerJS qui fait la même chose pour Gecko et TrifleJs pour IE. (La couverture de features n'est pas encore la même que PhantomJS cela dit, mais ça reste une piste à suivre).
L'API de tests fonctionnels se base sur une syntaxe simple à base de casper.start(url), .click(url) et de .then() pour les chainer. A noter que les .then sur le click ne semblent pas attendre la réponse de la requete mais simplement se baser sur le timeout (il reste possible d'utiliser directement les objets request/headers/status si nécessaire).
Le selecteur d'élément est proche d'un Nokogiri et utilise une syntaxe CSS3.
CasperJS permet aussi de prendre des screens au format jpg/gif/png/pdf. Utile pour de la non-regression de mise en forme d'un build à un autre. Utile aussi pour prendre une capture de la page si un test foire pour donner du contexte.
Néanmoins, la syntaxe d'écriture des tests est propre à CasperJS et est moins aboutie qu'un mocha.js par exemple. Dans la v2, ils prévoient de découper CasperJS du framework de test pour ne pas réinventer la roue et permettre d'utiliser du mocha, jasmine, etc.
CasperJS est déjà Jenkins-ready et des exports au format console, junit ou html sont déjà intégrés. Si nécessaire, on peut aussi appeller des scripts shells depuis Casper.
Le 22 Février est la journée mondiale de l'Open Data, et avait lieu à Paris un Hackathon, dans les locaux de Simplon, à Montreuil. Autant le dire tout de suite, c'était mal organisé. On était à peine douze en tout, en comptant les journalistes et les organisateurs.
Chacun a un peu présenté ce qu'il souhaitait faire et on s'est globalement répartis en 3 groupes : Open Data Ministère de l'Intérieur, Open Data Science et Santé, et Open Street Map.
De mon coté j'ai bossé avec Sabine Blanc, journaliste qui s'interesse à l'Open Data du Ministère de l'Intérieur. Le ministère a "ouvert" 266 jeux de données, mais dans des formats pas forcément exploitables (pdf, word, xls). Elle souhaitait les ouvrir tous pour en voir le pourcentage qui étaient réellement exploitables de manière à pouvoir dire si le travail du ministère en terme d'ouverture est atteint ou non.
Comme c'est chiant de faire ça à la main, je me suis proposé pour scripter un scrapper qui va automatiquement pré-remplir un Google Spreadsheet avec les infos interessantes et les liens pour télécharger et où il ne reste plus qu'à indiquer si oui ou non le fichier est utilisable.
Heureusement, il y avait parmis les participants Emmanuel Raviart d'Etalab, qui a bossé sur le site data.gouv.fr d'où je choppais mes infos. Grâce à lui je n'ai pas eu besoin de scrapper les pages comme un bourrin car il existe une API (en fait, il en existe 3), non documentée, qui permet de faire ce dont j'avais besoin.
En une aprem j'ai réussi à récupérer 55 jeux de donnée sur les 266 (pour cause de bug dans l'api, les jeux manquants étaient impossible à requeter). Heureusement, Emmanuel a pu me filer des liens vers les bons endpoint de l'API et j'ai pu finir le travail ce week-end et générer le fichier final.
Sur place on a pu rencontrer quelques personnes sympas, mais globalement c'était pas le hackathon qui restera le plus dans ma mémoire. Les gens partaient petit à petit sans qu'il n'y ai de présentation finale des travaux de chacun. Et puis un hackathon de 13h à 19h ça fait un peu court.
Le code que j'ai pondu est dispo ici : https://github.com/pixelastic/datagouv-scrapper et permet de récupérer sous format csv et json la liste des jeux de données fournis par un ministère donné.
La TakeOffConf à lieu à Lille. C'était cette année la seconde édition. Soutitrée "The Future of Web Technology", elle est à vocation européenne et s'adresse aux développeurs, et vise à toucher un grand nombre de sujets, sans forcément rentrer beaucoup dans la technique.
Deux jours de conférences, c'est intense, il y avait du très bon, et du moins bon. Je ne vais pas trop m'attarder sur le moins bon et surtout décrire les highlights.
LES TRÈS BONNES CONFÉRENCES
We made a hack, with fire, a gun and multiple robots.
Michal Wawra de Twilio nous présente une machine de Robinson qu'il a fait durant un hackathon. C'est un moyen compliqué de faire quelque chose de simple. Dans ce cas, c'était comment réussir à envoyer un sms (grâce à l'API Twilio) en passant par des billes qui coulent dans un tunnel en carton pour actionner un robot en plastique qui va s'agiter eu tout sens et déclencher une cellule de mouvement qui va faire déplacer un autre robot qui va amener une petite bougie sous un élastique qui, en brûlant, va libérer un régime de bananes accroché à une corde qui va actionner la gachette d'un pistolet Nerf qui va shooter une cible qi actionne un bélier qui va rentrer une disquette dans un lecteur qui va lancer le script final.
En plus d'être un sujet assez drôle, il en a profité pour extrapoler sur le fait que cette machine n'était finalement qu'une suite d'input et d'output dans des formats complétement différents. Il indiquait aussi qu'ils testaient unitairement chacune des parties mais que faire un test d'intégration complet était extremement couteux en initialisation, du coup ils n'ont pas pu en faire beaucoup avant la "mise en prod". De même, pour la partie avec la bougie, ils ont fait l'équivalent d'un try/catch dans le monde réel, c'est à dire au cas où le feu se répande anormalement, des capteurs devaient sonner une alarme.
Improv and Open-Source
Haleigh Sheehan de Github nous parle des parallelles qu'elle fait entre son boulot de musicienne de jazz, de joueuse dans un théatre d'impro, et de son boulot à GitHub dans le milieu de l'Open-Source.
Pour elle les deux milieux ont beaucoup de points communs, comme l'apprentissage de ses erreurs, la mise en public de son travail, le coté éphèmere, et l'importance du feedback.
Security Good Practices
Olivier Lacan, de CodeSchool (qui se révèle habiter à quelques rues de chez moi en fait), nous présente quelques bons conseils assez simples mais souvent oubliés pour améliorer notre sécurité, et la sécurité de nos apps.
Déjà, ne jamais fixer de limite au nombre de caractères maximum d'un mot de passe. Ne pas forcer de caractères spéciaux, majuscule, minuscule, etc. Plus on ajoute de règles, plus un password est difficile à retenir et donc plus on aura tendance à toujours utiliser le même ou bien à le noter quelque part. Il conseille 1Password (ou KeyPass) pour gérer son portefeuille de pass.
Le juste milieu entre User-Friendliness et Security est toujours très difficile à trouver. Il donne ensuite quelques outils pratiques comme GnuPG ou Meldium.com pour partager des accès à un service en ligne au sein d'une équipe sans pour autant utiliser plusieurs comptes, ni partager le mot de passe commun.
Il enchaine sur le fait que se faire voler son téléphone ou son laptop ne devrait pas être un problème. Le pass d'accès doit être assez complexe pour protéger l'accès. En ajoutant la possibilité de wiper le device à distance et en ayant fait une encryption complète du disque, tout va mieux. Truecrypt permet le chiffrement et permet même un plausible deniability.
Pour lui, il ne faut jamais faire de compromis sur la sécurité. Par exemple, même si la deadline est demain, il ne faut pas envoyer les pass en clair par mail parce qu'on n'a pas le temps de créer correctement un couple de clés. Parce qu'en commencant comme ça, un jour le système forcément sera compromis et un failure public qui révèle la totalité de la base client, qui fait la une des journaux, aura un impact bien pire sur les clients qu'un ou deux jours de retard initiaux (parallelle avec les TU, que le coût de correction d'un problème de secu est exponentiellement plus long plus il est mis en place tard).
Que https est un impératif, qu'il faut supprimer ses logs car ils contiennent des tas d'infos sur les gens, et qu'il est inutile de les garder si on ne s'en sert pas. Qu'il faut stocker les informations sur disque seulement le temps minimum légal, que si on a besoin de garder des données, il faut absolument les anonymiser (discussion intéressante auprès d'une bière après la conf avec un ancien de chez OVH sur ce sujet, comme quoi tout est anonymisé pour les employés). Et finalement, qu'il faut aussi faire attention aux library third party qu'on utilise et s'assurer qu'elles suivent les mêmes standard de qualité de sécu que son propre code.
The Bizarre App Experiments
Deux gars de Blackberry présentaient le framework de dev mobile Qt (prononcez Cute). Le framework est open-source, mais backé à temps plein par des gens de Blackberry. Il permet de faire du crossplatform iOS, Android, Blackberry et Windows Phone.
Ils ont présentés deux démos sympa sur scène. La première avec un capteur de rythme cardiaque, à enfiler autour de son torse, relié à un Blackberry en bluetooth qui lit un mp3 (Eye of the Tiger), et qui le stream en bluetooth vers des enceintes. Le pitch de la musique descends petit à petit et remonte en fonction du rythme cardiaque. Il faut donc s'agiter (courir, faire des pompes) pour remonter la musique au rythme correct. (Le capteur était un Wahoo Blue, ils utilisaient OpenAL pour la manipulation de l'audio et Qt 5.2. Testé uniquement sur Blackberry mais "devrait" marcher de la même manière sur iOs et Android).
Démo du code Bluetooth; découverte des devices, récupération du "heartbeat monitor" -spécifié dans la norme BT-, découverte des services du devices -battery, name, heartbeat, calories burnt, etc-. Tout ceci fonctionne à base d'events à chaque découverte sur lesquels ils se plugguent, et modifient le pitch en fonction.
Deuxième démo dans la même genre, cette fois avec une carte NFC à poser sur le blackberry qui lance un chrono de 10s. Le speaker devait alors courir à l'autre bout de la scène et revenir en moins de 10s, pour reposer la carte, qui lance un nouveau chrono de 9s, puis de 8s, etc. Et si le chrono atteint 0 le public devait lui lancer des balles en mousse. Les cards NFC coutent 0.5€ environ, très facile à mettre en place.
Idem, le timer est executé avec Qt et fire des events. Events fired aussi quand le NFC touche.
Developing Developers
Paul Verbeek, alias @hierow nous explique qu'il est difficile de trouver de bons dévelopeurs à embaucher. 80% d'entre eux sont autodidactes, donc les diplomes n'ont pas de valeur. Il est aujourd'hui bien plus facile d'apprendre le dev web qu'il y a trois ans (maturité des outils, experience, cours en ligne).
Pour lui, le meilleur dev web, est celui que l'on prends comme apprenti. Qui n'a jamais fait de dev avant, mais que ça interesse. Prendre un dev et le former au web va nécessiter de désapprendre beaucoup de choses.
Ne pas confondre Apprenti et Stagiaire. Un apprenti est Luke Skywalker, il sait ce qu'il veut devenir mais il ne sait encore rien. Un stagiaire est Anakin, il ne sait pas ce qu'il veut, il essaie et il deviendra peut-être quelque chose de complétement différent.
Il faut être un bon mentor pour espérer former un bon apprenti. Il faut savoir, et rester à jour sur les technos. Etre positif, et savoir motiver. Connaitre son apprenti, savoir ce qu'il aime, ce qu'il n'aime pas, ses forces, ses faiblesses. Savoir comment il apprends le mieux. Expliquer clairement, et écouter attentivement. Etre discipliné, et lui aussi. Instruire par l'exemple. Définir des règles et s'y tenir autant que lui. Et surtout ne jamais oublier que l'on est soit même un étudiant et qu'on apprends constamment.
Si on forme un dev front, il faut lui apprendre html, css, js. Mais s'il est intéressé par plus (back-end, ops, design) il faut l'aider aussi, et si cela sort de votre domaine de compétence, le diriger vers quelqu'un d'autre qui pourrait l'aider.
Il est normal de ne pas savoir au début, il faut juste savoir d'où part l'apprenti. Quelques questions comme "Qui est Tim Berners Lee ?" "Qu'est-ce qu'HTML5 ?" devrait permettre d'évaluer sa connaissance. Ce ne sont pas des questions pièges, juste pour savoir par quoi commencer.
Ne pas commencer à lui apprendre les table, iframes et floats. Faire du pair-programming pendant au moins une semaine, expliquer tout ce que l'on fait, lui poser des questions, s'assurer qu'il en pose aussi. Lui apprendre à ne pas utiliser w3schools, le rediriger vers MDN ou Webplatform.
Is IT really global ?
Contre-talk au talk sur Developing Developers. Comme quoi "c'est bien beau tout ces principes, mais en France on n'en n'a pas des boss comme ça, c'est pas dans la culture".
Très interessante conférence sur la Culture (dans le sens, les valeurs, les experiences qui entourent les gens du fait de leur milieu, de leur histoire). La culture est une prison, dans laquelle on tombe à la naissance et dont les barreaux sont invisibles. Impossible de voir sa propre culture tant que l'on ne va pas en voir une autre.
Histoire du têtard qui revient dans la mare après l'avoir quitté. On lui demande comment c'est le monde exterieur et il réponds que "c'est sec". On lui demande alors, l'air interloqué, "Sec ? Mais qu'est-ce que ça veut dire sec ?". Il réponds, "Ben, il n'y a pas d'eau quoi.". Et les autres tétards, encore plus interloqués de repondre "De l'eau ? Mais c'est quoi ?".
Confrontés à un même évenement, différentes cultures verront différentes choses, et réagiront différement, selon leurs experiences (directes ou indirectes). La culture est comme un oignon, il faut enlever plusieurs couches pour arriver au centre. Il faut d'abord passer les symboles (la langue, écrite et parlée, les expressions). Puis les Héros, les personnages historiques, réels ou imaginaires qui font partie de la culture d'un peuple. Après ça on arrive aux rituels, des actions que "l'on a toujours fait", même si on ne sait plus exactement pourquoi. Et après ça, finalement on arrive aux valeurs fondamentales.
Ces valeurs sont transmises par l'éducation, la religion, le travail et les lois. Hofstede a identifié 5 valeurs principales, sur lesquelles on peut placer chaque pays du monde sur une échelle de 1 à 100. Des pays opposés auront du mal à se comprendre. Ces valeurs sont Power Distance, Individualism/Collectivism, Masculinity/Feminity, Uncertainty Avoidance and Long Term Orientation
Notes: Il manque quelques CR dans la liste, pour cause de batterie à plat sur mon laptop. Voici quand même les vidéos qui valent le coup :
Comment le Guardian a optimisé son site mobile en terme de webperfs :
Paul Rouget nous explique les méandres de Firefox, ou comment ça se passe à l'intérieur de la machine quand le DOM, le CSS, le Js se mettent en place et comment tout ce beau monde communique avec le CPU et le GPU.
LES BONNES CONFÉRENCES
The web is innefficient, let's fix it
Justin Secor nous parle de green IT, et de l'impact sur l'environnement du Web. Il tente de faire un parallèle entre le poids d'une page web et la consommation d'énergie qu'elle implique. Son calcul se base sur la consommation d'électricité d'un datacenter sur un an (x Mb de donnée stockée coute y kWh).
A partir de là, il donne quelques exemples. La home page de la BBC pèse tant, elle a tant de visites par jour, donc sur une année, ça fait tant de Mb, donc tant de kWh. Conclusion : la home page de la BBC sur une année consomme moitié moins que la ville de Paris. Deuxième exemple, l'iPhone 5 qui ne consomme que 3.5Kw par an pour se recharger. Pour 9.100.000 iPhone, ca revient quand même à la consommation de Lille sur un an.
Finalement, il enchaine pour dire que nous devrions utiliser une métrique de consommation d'énergie dans nos projets, comme on emploi une métrique de poids des pages, de vitesse d'affichage, etc. Et qu'on se fixe une limite et qu'on travaille à la descendre.
Il conseille donc des SPA pour éviter de recharger trop de choses, et préfère les pixels noirs aux pixels blancs (là, je ne suis pas convaincu). Idem il enchaine sur l'utilisation de gzip, de css preprocessors, de limiter les requêtes, les reflows, les repaints pour diminuer notre consommation d'énergie.
Autant je suis d'accord avec le fond, autant ses méthodes de calculs me semblent oublier un trop grand nombre de paramètres pour être sérieuses. Cela dit, c'est un très très bon speaker et son talk est parfaitement bien rodé.
All your base are belong to us
@ColdFusion10 nous parle du security breach d'adobe et de ce que ça implique. Que leur communication était mauvaise, qu'ils ont communiqué sur 2.9 millions, puis 38 millions, puis 230 millions, et le code source de photoshop.
La base volée est facilement trouvable sur le net (users.tar.gz) et contient id, mail, encrypted pass et pass hint. Beaucoup de personnes indiquent leur mot de passe en clair dans le hint, ou de manière très facile à retrouver ("soleil en anglais", "prénom de maman").
Analyse des mails en .fr. 4 millions. dont des ville-.fr, cc-.fr, mairie-.fr, .gouv.fr. Mot de passe les plus populaire : 123456, photoshop, 12345678.
Il nous présente ensuite quelques outils comme shodanhq.com, qui est un google des devices connectés. On y trouve des imprimantes, des serveurs, des cameras de surveillance, avec leur adresse ip. Et beaucoup ont gardé un mot de passe par défaut (admin/admin). Il nous explique aussi que parfois le fichier de config des dns d'un serveur est accessible publiquement et permet d'obtenir la liste des sous-domaines, ce qui donne des pistes de vulnerabilités (jira.domain.com, phpbb.domain.com, confluence.domain.com, etc).
Nous parle ensuite en vrac de dnsenum.pl, nmap, exploit-db.com/search, openvas, metasploit, backtrack.
Il finit par rappeller les règles élémentaires d'utiliser https sur ses sites, et de surfer derrière un vpn. Et d'utiliser des softs open-sources plutot que propriétaires pour limiter le risque de backdoors.
Largescale Javascript applications
La présentation nous donnait des pointeurs sur de bonnes pratiques pour avoir du code javascript maintenable, même sur une large codebase ou sur une grande durée.
Une application largescale n'a pas forcément beaucoup de lignes de code, mais va toucher beaucoup de monde, ou rester en ligne pendant longtemps.
Il est facile d'écrire du Javascript, mais il est difficile d'écrire du js maintenable.
Avec jQuery il est facile de récupérer une soupe d'events difficiles à suivre, liés au markup, qui considèrent le DOM comme la source primaire d'informations, et qui rends le code extremement dépendant du design visuel. Le DOM est un singleton, global, et stateful, donc difficile à tester et maintenir. Il faut apprendre à ne plus dépendre du DOM, ne plus utiliser jQuery.
Aujourd'hui, de plus de plus de taches qui étaient reléguées au backend bougent sur le front, comme le templating ou le routing. Du coup, "If your app breaks without Javascript, you should treat it as a real language.". Le js produit se doit d'être testable, scalable, maintainable.
The secret to build large apps is to never build large apps. Break it in smaller parts.
Use a MVW framework. W stands for "Whatever works for you".
La manière dont le code est organisé (en fichiers, dossiers) influe sur la manière dont le code est testé et maintenu. Il suggère de ne pas diviser en controllers/, views/ etc mais par feature : feature1/, feature2/.
Diviser pour mieux régner. Splitter le code en petits modules, indépendant, réutilisables, unaware les uns des autres, et qui peuvent donc s'imbriquer facilement par injection de dépendance. Ca les rends plus faciles à tester et à maintenir.
Designing Apps for Little Fingers
Ensemble de best practices pour développer des apps pour enfants. Il n'y a pas de méthode bulletproof car le principe même d'être un enfant c'est qu'on est en train de grandir et que différents ages ne réagissent pas de la même façon. La conf se limite donc à la tranche 3-8 ans.
Toujours utiliser le mode landscape et pas portrait, les enfants sont habitués aux livres qui sont plus larges que hauts.
Penser que l'enfant tient la tablette avec deux mains, il ne faut pas lui demander d'appuyer sur un bouton en même temps qu'il la tient.
Il est très intuitif pour un enfant d'appuyer sur l'écran, et il a besoin d'un feedback immediat (ontouch, pas on release). Si pas de feedback tout de suite, il va réappuyer encore et encore. Aussi, ne pas faire de différence entre single tap et double tap.
Facile pour eux de dessiner en déplacant le doigt, par contre il faut s'attendre à ce que le doigt "saute" et donc que le trait soit fait avec des coupures.
Faire un Swipe d'un coté à l'autre est difficile, il vaut mieux proposer un bouton.
Darg'n'drop est intuitif, mais ne sera pas précis. De plus, il faut là aussi s'attendre à ce que l'enfant "lache" l'objet en cours de route, il faut donc le laisser où il est plutot que de le ramener au début.
De manière générale, toute ce qui nécessite plus d'un doigt est difficile.
Ne pas leur demander de secouer ou pencher la tablette, il risquent de ne pas maitriser le mouvement et la casser. Ne pas non plus mettre de musique de fond (pensez aux parents !).
Tout ce qui est action "adulte" (paiement, téléchargement, configuration) doit se trouver derrière une "baby gate". Un texte écrit indique quelle gesture l'adulte doit faire pour accèder aux options (pinch zoom, figure complexe), pour que l'enfant ne puisse pas le faire. Et changer la figure aléatoirement pour que l'enfant ne l'apprene pas par coeur en voyant son parent le faire.
La suite des advices étaient plus d'ordre générique game design, pas uniquement pour les bambins :
Avoir des buts clairs et intuitifs. Potentiellement un personnage virtuel qui dit "bonjour, je suis truc, on va faire ça". Ca permet à l'enfant de switcher mentalement du contexte "home page" de la tablette, à celui du jeu.
Rendre les éléments interactifs plus visibles que le background (différence de style visuel, glow, highlight, pulse, etc). Si pas d'action pendant 1-2s, highlight des éléments avec lesquels l'enfant peut intéragir.
L'enfant apprends en faisant des erreurs, donc bien marquer les erreurs (grosse croix rouge par exemple), mais garder les persos happy (pas de froncement de sourcils par exemple). Aussi, si échec la premiere fois, donner un indice. Si échec à nouveau donner autre indice. Si nouvel échec, faire un highlight de la solution. Mettre des rewards visuelles et sonores.
Utiliser des pictos consistants dans toute l'app et si possible d'une app à une autre, sans texte.
Si texte, utiliser la même font que celle utilisée dans les livres de lecture du pays en question (différent selon les pays). Si texte lu oralement, faire un système karaoké qui highlight les mots quand ils sont lus.
I have a NoSQL toaster, why should I have a NoSQL database ?
Présentation des db nosql, parce qu'on les qualifie par ce qu'elles ne sont pas, mais pas assez parce qu'elles sont.
Première question : pourquoi ne pas utiliser sql ? Parce que le scaling est difficile avec sql. Parce que maintenir un schema cohérent sur le long terme est presque impossible.
Il présente ensuite des tas de DB NoSQL en les classant selon différents types.
Les DB document-oriented comme mongoDB ou couchBase. Utilisent du json/bson pour stocker la data, et elles comprennent le format du document stocké. Elles peuvent faire du travail qui était habituellement fait par le back-end. CouchBase : ++scaling, ++consistently fast MongoDB : ++easy querying, --no scaling
Les DB au format clé/valeur. Deux versions, soit en mémoire sur une machine, soit distribué sur plusieurs. Si en mémoire sur une machine, extremement rapide. Si distribué, scale beaucoup mieux mais on entre dans de l'eventual consistency (Riak, Dynamo, Voldemort, Cassandra). Ils acceptent tous les writes, même s'ils sont fait en même temps sur deux noeuds (alors qu'il y a un lock en cas de non-distribution). Distributed : ++scaling, ++availability, --manual conflict fixing Non-distributed: ++fast, --scaling
Il m'a ensuite perdu en parlant de columnar db (cassandra hbase) qui sont bien adaptées à du big data, mais sont un cauchemar pour les ops.
Finalement, les bases orientées Graph (Neo4j) qui stockent des objets et les relations entre ces objets. Finalement on s'intéresse dedans plus aux relations qu'aux objets eux-même.
D3.js
Présentation de la lib js D3 pour faire de la dataviz. Output en html ou svg, facile à prendre en main mais aussi extremement puissant pour des besoins plus complexes. Extension Rickshaw spécialisée dans la time visualisation. La lib parait extremement complète et simple à prendre en main, j'ai envie de la tester au plus vite.
LES CONFÉRENCES MOYENNES
Your own adventure web
Robin Berjon, du W3C, prêchait pour un html plus extensible. La possibilité pour les devs front de créer leurs propres balises, et de leur ajouter des comportements particuliers, gérés par les attributs. Un moyen pour lui de sortir de la boucle infernale du "draft > implémentation browser > tests des devs > standard > implémentation partout".
Ca se rapproche assez des directives angular, et c'est un pas dans la bonne direction pour lui, mais il attends que ces primitives soient accessibles directement dans le browser pour tous les devs.
Il a mentionné hitchjs, une libraire js qui ajoute de nouveaux selecteurs css évolués.
OWASP Top 10
Par @airbone42, un recap des règles de bonne hygiène technique en rapport avec la sécu. Que du très basique globalement : attention aux injections sql, ne pas mapper en 1 pour 1 les champs de la db avec les champs d'un menu déroulant (genre si 2 = moderator et 3 = user, alors on peut déduire que 1 = admin).
Quelques exemples de bonne configuration typique Apache (et un lien vers github.com/ioerror/duraconf).
S'ensuit un rappel que ce qu'est un salt, une rainbow table, une attaque XSRF. Qu'il faut bloquer toutes les actions par défaut, et les autoriser au cas par cas plutot que l'inverse. Qu'il ne faut pas stocker un degré d'habilitation dans un cookie (oh, really ?) ni ajouter des infos importantes dans les commentaires HTML. Que toutes les actions "sensitives" (changer mail, changer identifiant, paiement, etc) doivent redemander le pass, même si l'utilisateur est déjà loggué.
Un rappel intéressant au global, mais rien de nouveau.
Régis Hanol, core contributor de Discourse (forum rails+ember) nous présente Ember. (Note: La présentation en elle-même était assez simpliste et n'apprenais pas beaucoup plus sur le framework que la lecture de la doc, mais j'ai pas mal discuté avec Régis durant les deux jours, et j'en ai appris plus sur Ember).
Ember prone le convention over configuration (comme rails dans l'idée, mais pas les mêmes conventions que Rails, du coup il n'y a pas d'affinité particulière entre les deux si ce n'est le mindset).
Il permet de faire des Single Page Application, en utilisant HandleBars comme moteur de templating en interne (ça limite un peu le templating dans la gestion des attributs html custom par exemple mais devrait s'améliorer dans les prochaines versions).
Il est possible de faire du SEO avec Ember... Enfin, avec Rails surtout. Il suffit d'injecter dans une balise noscript le contenu textuel de la page. Le serveur aura préalablement strippé tous les attributs cosmétiques (avatars, icons, etc). C'est ce qui est utilisé par Discourse.
Ember possède un mécanisme intéressant de rendering pour limiter le nombre de reflow/repaint, il attends que tous les events de sa queue soient effectués pour batcher tout ça. (Angular aussi doit faire quelque chose de similaire sous le capot, mais je n'ai pas trouvé de doc à ce sujet).
Finalement, Ember est jeune, le développement de Discourse a permis de mettre en avant des soucis de performances quand trop de views sont chargées en même temps (d'où le développement d'un principe de cloaking views qui unload les views qui ne sont plus dans le viewport). De même, ils n'utilisent pas ember-data car encore beaucoup trop buggué, ils font leurs appels http à la main.
A noter aussi que les tests d'Ember sont arrivés tard dans le cycle de dev, en ajoutant un member à la core team dont le taff principal était de couvrir l'appli de tests. Il n'y a clairement pas le même support derrière Ember que derrière Angular.
Singing Gophers
Présentation du langage Go, au travers d'un synthétiser de musique de la lib PortAudio (en C). Mais Go peut appeller du code C, et go est rapide (ben, oui parce que si goéland... petit blague pour voir ceux qui lisent mes CR jusqu'au bout), Go a des threads très légers et Go push de la donnée dans des tunnels (channels) qui sont des variables et qui recoivent de la donnée régulièrement.
Exemple d'un suite de fibonacci, on put les nombres dans un channel au fur et à mesure qu'on les génère, tout en continuant de looper dessus. On peut donc les afficher au fur et à mesure de leur génération.
Finalement, sa démo plus ou moins live codée permettait de jouer la marche impériale et donnait envie de tester Go.
LE RESTE
Using promises
Quentin Adam a tenté d'expliquer ce qu'étaient les promises et comment ça pouvait nous aider à sortir du callback hell. Si on connaissait déjà les promises, son talk n'apportait rien de neuf, et si on n'en avait jamais entendu parler, son accent anglais tellement français rendait le talk incompréhensible.
OpenDeviceLab
OpenDeviceLab est une asso internationale pour mettre à disposition des web devs de vieux devices (mobile phone, tablets) pour tester "facilement" son appareil sur toutes les plateformes. La conférence ressemblait plus à une publicité pour l'asso qu'autre chose. Pas été convaincu du tout.
Le seul point valide qu'il ait soulevé est que le parc des devices est beaucoup plus hétérogène que ce que l'on teste habituellement. Et que bien souvent nos tests sont fait dans des univers priviliégiés alors qu'un utilisateur réel aura bien souvent une connection pourrie, coupée par le métro, avec peu de batterie, des reflets sur son écran, etc.
Historique de Windows Azure.
ZZZZZzzzzz
Industrial Javascript
@Swiip nous parle de javascript, pour des développeurs Java. On nous présente tout le panel des outils autour du js, qui permettent au dev java de se retrouver dans un terrain un peu plus connu. Un peu foutoir, ça présente très vite angular (+ember, +backbone), Bootstrap, jshint, grunt (+gulp, +brunch, +jake), scss (+stylus, +less), coffeescript, haml (+jade), yeoman, jasmine, karma, phantomjs, mocha, chai, sinon. Un peu trop de choses à ingurgiter d'un coup, quoi.