• [^] # Re: Rx

    Posté par . En réponse au journal La programmation concurrente en mode Goto. Évalué à 1.

    C'est comme ça que Python fonctionne. Toutes les exceptions héritant de BaseException (genre SystemExit ou KeyboardInterrupt) sont déjà gérée comme ça. Note que ces exceptions ne sont pas invisible, les bonnes pratiques indiquent juste qu'il faut faire, sauf cas très particulier, un except Exception pour les laisser passer.

    Elles sont invisibles. Quelque chose qui n'est visible qu'au runtime est invisible c'est quelque chose qui peut arriver implicitement et ça rend presque impossible une validation par revue du code (c'est précisément ce que l'on recherche quand on dit qu'il faut être explicite). Je sais que ça fait partie du langage (on peut écrire ce que l'on veut dans les PEP, le monkey patching existe en python, c'est un langage dynamique ça autorise à faire un tas de choses de manière implicite). C'est aussi le cas de mon langage de prédilection (java), hein ? C'est juste que ça limite la manière dont je vais exprimer mon code asynchrone.

    Je le répète: les problèmes d'init/teardown (en particulier dans le cas d'un crash) sont ce qu'il y a de plus compliqué en asynchrone, l'intérêt de trio est de te donner un contexte pour gérer ça simplement (on fonctionne avec des paradigmes très proche de ce qu'on ferait en programmation single thread classique).

    Pourquoi ne pas gérer ça dans une forme de machine à état ? C'est ce que font les circuit breaker et les systèmes à acteurs (OTP ou akka le font pour toi), ça marche très bien et tu as la garantie que ton programme ne va pas exploser en vol à cause d'une erreur quelque part. Lancer une exception et carpe diem ce n'est pas sécurisé.

    « let it crash » c'est particulier. Ça dépend de ce que tu fais comme application. Si tu es dans un monde de microservice, avec un kubernetes qui te redémarre pourquoi pas (et encore...1 ) si tu fais une application mobile par exemple ce n'est pas envisageable.

    L'exception ne modifie que le context de la coroutine touchée, c'est au développeur de choisir si la coroutine en question travaille sur toutes les données ou bien sur un sous ensemble isolé du reste du système.

    Interrompre son taf c'est déjà modifier son contexte, le fait de sortir manu military des blocs de codes détruits un tas de variables,... Imposer un try/except à tous les niveaux c'est difficilement tenable. Et ça empêche de continuer normalement son travail avant de gérer l'erreur.

    Ou bien des locks à grain fin, ce que la programmation asynchrone rend beaucoup plus simple qu'en utilisant des threads classiques.
    De mémoire Redis fonctionne de cette façon (il implémente sa propre boucle asynchrone et lance une coroutine par connection client), on peut activer un journal de logs mais c'est pour rendre les données persistantes (donc dans tous les cas on se retrouve avec des coroutines qui travaillent sur les même données dans la base).

    Redis n'est pas capable de gérer de multiples CPU et ne permet pas de véritablement gérer des écritures sur différents nœuds. Je ne suis pas certains qu'il fasse vraiment du lock à grain fin. Il fait du lock oui... Pour utiliser plusieurs CPU il faut faire du sharding de ton coté. À comparer avec hazelcast qui est une base de données comparable, mais architecturée en P2P avec un sharding automatique (ce qui permet de réduire la pression sur les event log - tu en crée un par shard). Tu peux aussi regarder du coté de cassandra qui fait précisément ça (aussi en P2P).

    Sinon un autre exemple (quoi que plus bas niveau) de ce type de besoin serait le Kernel Linux. Travailler par passement de messages est intéressant mais coûteux (cf. les débat kernel monolithique vs microkernel).

    Ah mais carrément ! Ça ne fonctionne pas pour tout. Le noyau a notamment besoin de débit et de latence délirante :

    • une latence sur les IRQ serait vraiment affreux pour notre utilisation
    • envoyer une image à la carte graphique par messages serait affreux

    Pour l'aspect sémantique c'est intéressant, mais j'ai plus le temps d'en parler tout de suite.


    1. ça va crasher toutes les requêtes en cours, tu as une centaine de requêtes en cours de traitement sur ton nœud tu as potentiellement 99 requêtes KO pour une en erreur... Pas cool.