Concepteurs utilisateurs

Il faudrait que les concepteurs soient contraints d’utiliser leurs réalisations pendant quelques mois. Spéciales dédicaces aux architectes de la gare SNCF de Montpellier et de la Villa Méditerranée marseillaise.

★ Prospective Python

J’ai retrouvé un vieux brouillon de mon intervention aux rencontres Django (novembre 2012) donné sous le titre « Pourquoi je ne veux plus utiliser Django ? ». Je le publie en l’état et je reviens dessus à la fin.

Titre clairement provocateur pour cette intervention aux rencontres Django de Toulouse qui est né d’un ressenti que j’ai depuis quelques mois/années. Je vais essayer de détailler les doutes que j’ai sur le futur de Django et Python. Je vois plusieurs défis majeurs pour les mois à venir :

Python 3

Python 3.0 est sorti il y a 4 ans quasiment jour pour jour (3 décembre). Qui l’utilise aujourd’hui ? Qui a un projet web en production qui repose sur cette version ? Très peu. Principalement car la rétro-compatibilité n’a pas été conservée pour cette version ce qui pose clairement des problèmes de mise à jour des bibliothèques sans lesquelles un projet ne peux pas se faire aussi rapidement qu’en 2.X. C’était un risque énorme qui a été pris et la communauté en paye le prix fort. Combien faudra-t-il encore d’années pour que cela change ? Quels sont les gains réels ? Qu’en est-il de Pypy ?

Et quitte à réapprendre une partie du langage, est-ce qu’il ne faudrait pas aller voir ce qui se fait ailleurs ?

Node.js

Node.js is a tumor on the programming community, in that not only is it completely braindead, but the people who use it go on to infect other people who can’t think for themselves, until eventually, every asshole I run into wants to tell me the gospel of event loops. — Ted Dziuba, Fibonacci’s lover

Phénomène de mode ou futur proche ? Il y a énormément de côtés plaisants à Node.js : notion de callbacks, promesse d’une validation des données partagée entre le client et le serveur, performances, etc. Par contre le manque de maturité est vite bloquant aussi : traceback incompréhensibles, outils insuffisants, manque de bonnes pratiques et de retours d’expériences, etc. Certains ont clairement fait le choix de s’engager dans cette voie mais ça me rappelle bien trop l’engouement autour de Ruby on Rails il y a quelques années auquel j’ai résisté et dont je me félicite aujourd’hui (ce n’est pas une critique de RoR sans lequel Django ne serait très certainement pas ce qu’il est aujourd’hui).

Flask

OH: "Microframework (n): A small amount of crap. See also Framework (n): A large amount of crap." — @nikita_ppv

Django se complexifie. Release après release. L’héritage des class-based views est assez symptomatique du problème (disclaimer : j’ai participé à ce sac de nœuds…) de la généralisation à outrance qui nuit au framework. Les alternatives comme Flask sont alléchantes mais il y a des frameworks basés sur Node.js qui arrivent aussi et qui apportent des réponses aux problématiques de temps-réel, ou plutôt…

Temps-humain

J’ai abandonné le terme temps-réel qui ne veut pas dire grand chose au profit de celui-ci qui repose sur la perception humaine de rapidité que l’on peut avoir avec une interface et qui me semble beaucoup plus proche de la réalité. Il est toujours relativement compliqué d’utiliser les websockets avec Django et même Python. Comment développer les applications interactives de demain ?

Et après ?

It’s so much easier to talk about how something sucks than to talk about how it could be awesome. Negativity is for the lazy. — @defunkt

Parlons d’avenir et de web. Il y a eu 2/3 évolutions ces dernières années dans les implémentations et leurs usages (car les standards existent depuis un moment) permettant d’introduire de nouveaux paradigmes dans le développement d’applications. Voici quelques exemples de pistes à explorer :

  • API-first : le modèle MVC a pris du plomb dans l’aile avec la multiplication des périphériques et des moyens de consommation des données, il faut repenser la gestion de la donnée ;
  • asynchronicité : certaines requêtes mettent plus de temps que d’autres mais ce qui importe c’est la perception qu’à le visiteur de la réactivité de votre application, il manque des outils permettant de gérer ces cas aux limites qui font pourtant parfois la valeur réelle de l’application ;
  • single page apps : de plus en plus de sites se développent en n’utilisant qu’une seule page, il y a même un livre dédié à ce concept, or les frameworks ont bien souvent un contrat unique de requête/réponse par page qui répond mal aux exigences d’une mise à jour partielle de page ;
  • mobilité : le web est dans de plus en plus de poches, à portée de doigts, avec une inégalité des accès au réseau en fonction de la localisation. Il faudrait que les frameworks soient adaptés à ces nouveaux usages avec du stockage local et de la synchronisation, avec des rendus adaptés aux vitesses de connexion, avec des concepts moins gourmands en énergie et en bande passante.

J’espère que ces pistes seront partie prenante des discussions relatives à Django 2.0 ou de nouveaux frameworks que j’espère en Python. Ces nouveaux paradigmes me redonneraient à coup sûr l’envie de développer en utilisant Django ;-).

Retour en 2015

Malheureusement, 2 ans plus tard, j’ai toujours les mêmes doutes sur le futur de Python/Django. J’expérimente avec ReactJS depuis maintenant un an. Relire ce tweet me fait sourire de naïveté :

ReactJS is to Web Components what microformats were to Semantic Web. And I can’t conclude anything from that.

Il y a une effervescence dans la communauté JavaScript qui serait grisante si elle ne cessait de réinventer la roue. Plusieurs fois. Mais force est de constater qu’il y a des pistes intéressantes dans ReactJS : ils ont justement « repensé la gestion de la donnée » avec Flux, ils permettent l’asynchronicité, on peut faire des SPA sans se prendre la tête, ils expérimentent avec la mobilité (React Native et GraphQL/Relay ont été annoncés ce jour). Autant d’approches que je n’ai pas vues dans la communauté Python. Je ne compte pas dire au revoir à Python (cache) car je prends toujours beaucoup de plaisir à coder avec mais je commence à me poser de sérieuses questions sur sa pertinence pour des projets Web réactifs (huhuhu).

Merci pour votre attention

If you’re in the audience at a scientific conference, what do you really want? For me, that’s quite simple: understanding the papers that seem relevant to me. So as a speaker, focus not on what you want, but what the audience wants. Your personal goal is to get your message across to those researchers for whom it is relevant. Note in particular that attention is not a part of your goal. Sure, in order to understand a message, people will likely need to pay attention, but solely capturing (or stealing) that attention does not reach your goal. Furthermore, if people get your message without paying attention, that seems like a win–win situation. Therefore, instead of focusing on getting attention, focus on maximizing the use of the attention you get.

Thank you for your attention (cache)

Remarques intéressantes sur l’attention et la clôture d’une intervention.

Systèmes réactifs

We believe that a coherent approach to systems architecture is needed, and we believe that all necessary aspects are already recognised individually: we want systems that are Responsive, Resilient, Elastic and Message Driven. We call these Reactive Systems.

The reactive manifesto (cache)

Je me demande dans quelle mesure ce type de système est atteignable sans introduire une trop grande complexité/intelligence.

★ Cours IUT : Construction collaborative

Aider chaque élève à organiser ses connaissances et à progresser dans sa formation, à devenir compétent, c’est lui apprendre à créer des ensembles, des groupes, à prendre conscience de l’existence de patterns. La première activité cognitive, quelque soit le niveau scolaire ou la discipline, est de Trier-Classer-Ranger.

Faire toujours la même chose à bon escient, c’est être compétent. (cache)

On a débuté le cours avec un IceBreaker (mad, sad, glad) qui apporte beaucoup d’informations au final sur le caractère des participants dès le premier échange. J’ai ensuite formé trois colonnes sur le tableau en les invitant à venir les compléter avec des post-it :

  • Compétences
  • Expériences
  • Appétences

Des choses intéressantes sont sorties comme une forte envie de développer mais aussi de créer une agence web avec des compétences allant de monter un réseau à scrum en passant par Prestashop, Joomla ou Wordpress. Cette fois les niveaux semblent plus proches mais les horizons différents ce qui m’intéresse beaucoup en termes de partage de cultures et d’entraide.

J’ai ensuite proposé que l’on définisse ensemble ce que l’on mettait derrière Web Mobile avec trois nouvelles colonnes :

  • Web Mobile
  • ?
  • !Web Mobile

Cela a permis de discuter de pas mal de concepts, allant du paiement sans contact au streaming vidéo en passant par Objective-C ou PhoneGap. Cette tentative de définition était avant tout un prétexte à la discussion. J’ai pu expliquer certains des concepts qui n’étaient pas forcément maîtrisés par tous comme les API natives ou les latences réseaux. J’ai essayé d’encourager certains à expliquer aux autres ce qu’ils entendaient par les termes qu’ils énonçaient. Contrairement à mon positionnement de sachant lors du premier groupe, je souhaite plus aller vers de la facilitation et de la discussion cette fois-ci, j’estime qu’ils ont les bases suffisantes pour cela.

Une fois gagné en fluidité, on est passé à « ce que l’on veut faire ensemble », sans aucune contrainte de ma part. On a simplement listé ce dont ils avaient envie pour ce cours. J’ai donné une approximation des tailles relatives entre les cartes pour qu’ils puissent ensuite les classer par priorité descendante en connaissance de cause. Nous sommes arrivés au backlog suivant :

  1. AngularJS
  2. Performance Web
  3. PHP-MySQL
  4. Canvas
  5. NodeJS
  6. UI/UX

Avec une listes additionnelle de petits items à insérer au moment fortuit ou dans les temps-morts :

  1. AJAX/JSON
  2. Bootstrap
  3. Flexbox
  4. Veille techno
  5. Mobile-First
  6. SASS/LESS

Au final, ça n’a pas tout a fait à voir avec le Web Mobile (ni mes compétences !) mais l’expérience m’intéresse pour voir ce que cela produit en termes d’implication et de curiosité.

On a terminé par établir clairement les règles du jeu. S’il y a une seule chose que j’ai retenu de l’intervention de Dan Mezick c’est qu’il est important de définir des règles claires dès le début et il se trouve que j’ai toujours une profonde aversion pour les notes. En combinant les deux, j’ai proposé aux élèves d’établir leur propre système de notation. Leur choix s’est porté vers l’auto-évaluation (après avoir hésité sur un projet suivi qui demandait de regrouper l’ensemble des technologies quitte à produire un patchwork artificiel).

Ils repartent avec trois tâches à effectuer pour la fois prochaine :

  • je vais essayer de mettre en place une routine (voir lien en extrait) de veille technologique en leur proposant de revenir avec 3 liens par séance à commenter pour commencer le cours ;
  • j’ai expliqué pour chaque carte la matière avec laquelle il fallait arriver en cours (avoir lu le tutoriel d’AngularJS, avoir fait une pré-analyse des performances pour un site de leur choix, etc) ;
  • m’envoyer par email l’une de leurs réalisations.

Menace commune

If killing large numbers of civilians does not have a military impact, then what, Wilson asks, is the purpose of keeping nuclear weapons? We know they are dangerous. If they turn out not to be strategically effective, then nuclear weapons are not trump cards, but time bombs beneath our feet.

Why did Japan surrender? (cache)

Les faits, aussi récents qu’anciens, nous montrent qu’il faut une menace commune pour que les peuples se soudent et œuvrent ensemble. Or nous en avons deux : le nucléaire et le changement climatique. Quelles chances pour l’Humanité ! L’Homme est semble-t-il aussi la première espèce terrestre qui peut sciemment décider de sa survie…

One answer to the Fermi paradox is that nobody makes it through — that climate change is fate, that nothing we do today matters because civilization inevitably leads to catastrophic planetary changes.

Is a Climate Disaster Inevitable? (cache)

How to fix your Elasticsearch cluster stuck in initializing shards mode?

You know, for search

Elasticsearch is one of my favorite piece of software. I’ve been using it since 0.11 and deployed every version since 0.17.6 in production. However, I must admit it’s sometimes a pain in the ass to manage. It can behave unexpectedly and either vomit gigabytes in your logs, or stay desperately silent.

One of those strange behaviour can happen after one or more data nodes are restarted. In a cluster running either lots of nodes or lots of shards, the post restart shard allocation can take forever and never end.

This post is about investigating and eventually fixing this behaviour. You don’t need to have a deep knowledge of Elasticsearch to understand it.

Red is dead

The first evidence something’s wrong comes from the usual cluster state query.

curl -XGET http://localhost:9200/_cluster/health?pretty
{
  "cluster_name" : "myescluster",
  "status" : "red",
  "timed_out" : false,
  "number_of_nodes" : 20,
  "number_of_data_nodes" : 16,
  "active_primary_shards" : 2558,
  "active_shards" : 5628,
  "relocating_shards" : 0,
  "initializing_shards" : 4,
  "unassigned_shards" : 22
}  

This is all but good.

The status: red is a sign your cluster is missing some primary shards. It means some data are still completely missing. As a consequence, queries on these data will fail and indexing will take a tremendous amount of time. When all the primary shards are back, the cluster switches in yellow to warn you it’s still working but your data is present.

initializing_shards: 4 is what your cluster is currently doing: bringing back your data to life.

unassigned_shards: 22 is where your lost primary shards are. The more you have there, the more data you’re missing and the more conflict you’re likely to meet.

Baby come back, won’t you pleaaaase come back?

What happened there?

When a data node leaves the cluster and comes back, Elasticsearch will bring the data back and merge the records that may have been written during the time that node was away. Since there may be lots of new data, the process can take forever, even more when some shards fail at starting.

Let’s run another query to understand the cluster state a bit better.

curl -XGET http://localhost:9200/_cat/shards
t37       434 p STARTED 12221982  13.8gb 10.0.0.22   datanode02
t37       434 r STARTED 12221982  13.8gb 10.0.0.23   datanode03
t37       403 p INITIALIZING 21620252  28.3gb 10.0.0.22   datanode02
t37       404 p INITIALIZING 5720596    4.9gb 10.0.0.22   datanode02
t37       20  p UNASSIGNED
t37       20  r UNASSIGNED
t37       468 p INITIALIZING  8313898  12.3gb 10.0.0.22   datanode02
t37       470 p INITIALIZING  38868416 56.8gb 10.0.0.22   datanode02
t37       37  p UNASSIGNED
t37       37  r UNASSIGNED
t37       430 r STARTED 11806144  15.8gb 10.0.0.24   datanode04
t37       430 p STARTED 11806144  15.8gb 10.0.0.25   datanode05
t37       368 p STARTED 34530372    43gb 10.0.0.25   datanode05
t37       368 r STARTED 34530372    43gb 10.0.0.23   datanode03
...

This is indeed a sample of the real output, which is actually 5628 lines long. There’s a few interesting things here I want to show you.

Every line is under the same form.

The first field, t37, is the index name. This one is obviously called t37, and it has a huge number of primary shard to store the gazillon posts I’ve written over the years.

The second field is the shard number, followed by either p if the shard is a primary one, or r if it’s a replica.

The fourth field is the shard state. It’s either UNASSIGNED, INITIALIZING or STARTED. The first 2 states are the ones we’re insterested with. If I run the previous query | grep INITIALIZING and | grep UNASSIGNED, I’ll get 4 and 22 lines respectively.

If you need a fix…

First, let’s take care of the 22 unassigned shards since they’re the easiest to fix. What we’re going to do is force the shards allocation. Since we’re lazy, let’s do some scripting here.

for shard in $(curl -XGET http://localhost:9200/_cat/shards | grep UNASSIGNED | awk '{print $2}'); do
    curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
        "commands" : [ {
              "allocate" : {
                  "index" : "t37", 
                  "shard" : $shard, 
                  "node" : "datanode15", 
                  "allow_primary" : true
              }
            }
        ]
    }'
    sleep 5
done

What we’re doing here is forcing every unassigned shard allocation on datanode15. Depending on the shards size, you’ll probably have to assign them in various nodes. If you’re playing with very small shards, don’t worry, Elasticsearch will reallocate them for you once they’re up.

Let’s run the cluster health query again, will you?

curl -XGET http://localhost:9200/_cluster/health?pretty
{
  "cluster_name" : "myescluster",
  "status" : "red",
  "timed_out" : false,
  "number_of_nodes" : 20,
  "number_of_data_nodes" : 16,
  "active_primary_shards" : 2568,
  "active_shards" : 5638,
  "relocating_shards" : 0,
  "initializing_shards" : 16,
  "unassigned_shards" : 0
}  

Great news, isn’t it? All our previously unassigned shards are now active or assigned. Unfortunately, things aren’t fixed yet.

I still haven’t found what I’m looking for

Let’s run that query once more a few minutes later.

curl -XGET http://localhost:9200/_cluster/health?pretty
{
  "cluster_name" : "myescluster",
  "status" : "red",
  "timed_out" : false,
  "number_of_nodes" : 20,
  "number_of_data_nodes" : 16,
  "active_primary_shards" : 2580,
  "active_shards" : 5650,
  "relocating_shards" : 0,
  "initializing_shards" : 4,
  "unassigned_shards" : 0
}  

See? There are 4 shards still initializing. Guess what? I’m sure they’re the ones the first query already spotted. Let’s query the shard listing again.

curl -XGET http://localhost:9200/_cat/shards | grep INIT
t37       403 p INITIALIZING 21620252  28.3gb 10.0.0.22   datanode02
t37       404 p INITIALIZING 5720596    4.9gb 10.0.0.22   datanode02
t37       468 p INITIALIZING  8313898  12.3gb 10.0.0.22   datanode02
t37       470 p INITIALIZING  38868416 56.8gb 10.0.0.22   datanode02

Interesting isn’t it? Every stuck shard are on the same node. This is not really a surprise though.

If we try to run the reroute query, it will fail because the primary shard is not yet active.

[2015-01-25 11:45:14,569][DEBUG][action.admin.cluster.reroute] [masternode01] failed to perform [cluster_reroute (api)]
org.elasticsearch.ElasticsearchIllegalArgumentException: [allocate] allocation of [t37][403] on node [datanode02][uvM8ncAjTs2_HER9k6DMow][datanode02.t37.net][inet[/10.0.0.22:9300]]{master=false} is not allowed, reason: [YES(shard is not allocated to same node or host)][YES(node passes include/exclude/require filters)][NO(primary shard is not yet active)][YES(below shard recovery limit of [2])][YES(allocation disabling is ignored)][YES(allocation disabling is ignored)][YES(no allocation awareness enabled)][YES(total shard limit disabled: [-1] <= 0)][YES(no active primary shard yet)][YES(disk usages unavailable)][YES(shard not primary or relocation disabled)]
  at org.elasticsearch.cluster.routing.allocation.command.AllocateAllocationCommand.execute(AllocateAllocationCommand.java:221)
  at org.elasticsearch.cluster.routing.allocation.command.AllocationCommands.execute(AllocationCommands.java:119)
  at org.elasticsearch.cluster.routing.allocation.AllocationService.reroute(AllocationService.java:131)
  at org.elasticsearch.action.admin.cluster.reroute.TransportClusterRerouteAction$1.execute(TransportClusterRerouteAction.java:91)
  at org.elasticsearch.cluster.service.InternalClusterService$UpdateTask.run(InternalClusterService.java:328)
  at org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.run(PrioritizedEsThreadPoolExecutor.java:153)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
  at java.lang.Thread.run(Thread.java:745)

Then, what can we do? Unfortunately not much except restarting the node. Hopefully there’s only one of them.

Tell me whyyyyyyyyy

You and me together, fighting for our cluster

If you’re asking, yes, I love Jimmy Sommerville, but that’s not the point.

There’s some literature about shards never initializing and cluster restart taking ages on the Web. From what I’ve understood, such a stuck state can be reached when some shards fail to start and nothing’s done about it. Unfortunately, I didn’t find anything in my logs related to the shards that were stuck, so I have no idea how it happened.

That’s all folks, this post about tracking and fixing your shard allocations issues is over. I hope you enjoyed reading it as much as I enjoyed spending my weekend trying to fix it. Next time, we’ll see how pink unicorns are your personal development worst ennemies. Stay tuned!

★ Cours IUT : Web Mobile

The more I build for the web, the more the term ‘device-agnostic’ endears itself to me.

I used to think it merely dealt with basing responsive breakpoints on content rather than particular devices, but there’s more to devices than the size of their screens. A device-agnostic approach also takes into account infinite combinations of screen resolution, input method, browser capability, and connection speed. With such a wide range of possibilities, the sensible thing to do is to zero in on the harshest conditions (or toughest things to deliver) and build from there. Like cars designed to perform in extreme heat or on icy roads, websites should be built to face the reality of the web’s inherent variability. In my mind this approach addresses the following from the beginning:

  • Hostile browsers
  • Tiny screens
  • Slow connection speeds
  • Touch inputs

Device-Agnostic (cache)

Je démarre un cours intitulé Web Mobile avec une nouvelle classe demain, j’ai 28 heures réparties en matinées. La première séance de découverte sera l’occasion de définir ensemble ce que l’on entend par Web Mobile car je n’ai pas de définition, je ne suis même pas sûr que ça veuille vraiment dire quelque chose (mais bon c’est moi qui ait proposé le titre à la responsable alors mea culpa).

Je compte pour cela faire usage d’outils à base de sujets/concepts, de priorisation, de réajustement et de flux. Toute ressemblance avec des outils liés à l’agilité serait forcément fortuite. Ce n’est pas encore tout à fait clair pour moi et c’est une bonne chose, ce sont des outils que je souhaite inventer/adapter/tordre/jeter avec les participants. Mon objectif est qu’ils arrivent à exprimer leurs connaissances actuelles et leurs souhaits pour ce cours. Afin que l’on puisse ensuite décider ensemble de ce que l’on va traiter tout en réajustant en cours de route s’il le faut.

Il devrait y avoir une douzaine de personnes plus techniques que la dernière fois, ce qui donne une inertie de groupe moins importante. De quoi explorer de nouvelles façons de partager et de produire collectivement. On va forcément parler de mobile-first (cache) et de challenges pour les web designers (cache), je suis curieux et impatient de voir ce qu’ils vont me proposer en retour…

Voisinage en Python

J’ai besoin de connaître les articles précédents et suivants pour le blog et maintenant pour ces notes, je suis arrivé à la version suivante en Python qui produit un générateur à partir d’un itérable grâce au mot-clé yield :

def neighborhood(iterable, first=None, last=None):
    """
    Yield the (previous, current, next) items given an iterable.

    You can specify a `first` and/or `last` item for bounds.
    """
    iterator = iter(iterable)
    previous = first
    current = iterator.next()  # Throws StopIteration if empty.
    for next in iterator:
        yield (previous, current, next)
        previous = current
        current = next
    yield (previous, current, last)

Il me fallait surtout la possibilité de spécifier un premier/dernier item pour avoir un lien sur le premier article publié vers les pensées plus anciennes ou la première note vers les tweets archivés.

Luxe, espace et temps

This doesn’t mean I’ll be liveblogging a lot of ham-fisted attempts to turn “everything” off. But it does mean making mindful decisions about the quality of any input that I check repeatedly – as well as any “stuff” I produce. Everything. From news sources to entertainment programming, and from ephemeral web content down to each email message I decide to respond to. The shit has to go, inclusive.

Better - Merlin Mann (cache)

Je me suis rendu compte récemment qu’après avoir expérimenté le luxe de réduire mes besoins matériels, jeté ma télévision par la fenêtre©, foutu mon portable aux chiottes©, j’ai aujourd’hui le luxe d’avoir peu de contraintes d’espace et de temps. C’est une chance que j’apprécie chaque jour. Je suis avec intérêt les aventures de Thomas pour réduire son empreinte (cache).