Nouvelle release de crossbar: historique des events et crypto


Je suis méga à la bourre. Entre les tickets github qui s’accumulent, les comments auxquels j’ai toujours pas répondu et la liste d’articles à écrire qui augmente au lieu de diminuer (mais comment, bordel, comment ?), j’ai vraiment du mal à suivre.

Je dois toujours un article sur Polymer + Crossbar à Tavendo. Et il faut que je fasse un tuto sur l’authentification également (en attendant, y a des exemples plus à jour).

Fichtre.

En attendant, je vais en profiter pour faire un article vite fait sur la dernière release, puisque Crossbar, le routeur WAMP, passe en 0.12.

Comme d’hab, correction de bugs, amélioration du support de Python 3, plus de docs et d’exemples, blablabla…

Mais ce qui est vraiment intéressant, c’est l’historique des évènements.

Normalement un évènement est éphémère, dans le sens où une fois qu’il a été propagé, vous ne pouvez plus le recevoir. Si vous arrivez après la fête, c’est terminé.

C’est un problème, par exemple si vous redémarrez un client qui a besoin de ces évènements. Ou si vous implémentez un client qui veut savoir ce qui vient de se passer avant de se pointer, comme dans le cas d’un chat : on veut avoir les derniers messages postés.

Par défaut, l’historique n’est pas activé, puisqu’il y un coût pour chaque pub/sub. On doit explicitement le demander pour chaque event dans le fichier de config :

{
   "name": "realm1",
   "roles": [
   ],
   "store": {
      "type": "memory", # ou stocker l'historique
      "event-history": [
         {
            "uri": "mon.uri.pour.un.event", # quel type event
            "limit": 10000 # combien d’events stocker
         }
      ]
   }
}

type n’accepte pour le moment que memory, qui est une simple liste en mémoire dans crossbar, et bouffe donc de la RAM. On perd aussi l’historique au redémarrage du routeur, mais ça a l’avantage d’être très rapide.

Pour la prochaine version, Tavendo va implémenter un stockage dans une base lmdb et si ils font une belle API, on peut s’attendre à voir fleurir des backends pour SQLAlchemy, Django, Redis, etc.

event-history prend un liste d’events (les URIs peuvent utiliser les jokers introduits dans la version précédente), on met la limite du nombre total d’events à stocker pour cet URI en particulier.

Pour profiter de l’historique côté client, il faut obligatoirement avoir un abonnement à un event dont les messages sont sauvegardés. On ne peut pas récupérer l’historique de messages auxquels on n’est pas abonnés : forcer l’abonnement oblige en effet le client à passer le check des permissions.

Par exemple, en JS, d’abord on s’inscrit:

var promise = session.subscribe('mon.uri.pour.un.event',
   function (args, kwargs, details) {
      // bon là vous faites bien ce que vous voulez avec les nouveaux events
      //, car ça n’a rien à voir avec l’historique
   }
)

Puis on demande les events:

promise = promise.then(function (sub) {
      // L’abonnement retourne un objet "subcription" qui possède l’id
      // dont on a besoin pour demander l’historique des events.
      // On fait un petit RPC sur la meta API 'wamp.subscription.get_events'
      // qui demande aux routeurs tous les X derniers events qui matchent
      // notre abo. Ici x = 10
      return session.call('wamp.subscription.get_events', [sub.id, 10]);
)

Et enfin, on a droit à l’histo:

promise.then(function (history) {
    console.log(history.length, " events:");
    history.forEach(function(event){
        console.log(event.timestamp, event.publication, event.args[0]);
    })
 });

En Python, le code pour récupérer l’histo est logiquement:

import asyncio
from autobahn.asyncio.wamp import ApplicationSession, ApplicationRunner
 
 
class Component(ApplicationSession):
 
    async def onJoin(self, details):
 
 
        def on_event(i):
            print("Got: {}".format(i))
 
        # pareil on chope la souscription
        sub = await self.subscribe(on_event, u'mon.uri.pour.un.event')
        # et on demande la liste des 10 derniers events pour cet abo
        events = await self.call('wamp.subscription.get_events', sub.id, 10)
        # et on boucle. Et on kiff await parceque putain c’est pratique.
        for event in events:
            print(event['timestamp'], event['publication'], event['args'][0])
 
    def onDisconnect(self):
        asyncio.get_event_loop().stop()
 
 
if __name__ == '__main__':
    runner = ApplicationRunner("ws://127.0.0.1:8080/ws", 'realm1')
    runner.run(Component)

L’autre point phare de cette release, c’est la dépréciation de Mozilla Persona comme méthode d’authentification (le projet est dead) et la promotion de deux nouvelles méthodes: les certificats TLS et les paires de clés publiques/privées (Curve25519 pour le moment).

C’est une très bonne nouvelle, car ça veut dire plus de mots de passe dans les fichiers de configuration en production pour identifier vos propres clients qui ont forcément des privilèges supplémentaires.

Je reviendrais là dessus en faisant le tuto sur l’authentification.

Une release chouette donc. Mais qui introduit plein de dépendances à des extensions en C qui pourraient être optionnelles, ce qui rend l’installation plus compliquée. Je suis en train de discuter avec la team pour voir si on peut arranger ça, mais Tobias à l’air plutôt pour les garder. Si vous aussi vous voulez garder la simplicité de la base pure Python, rejoignez la discussion.

Enfin, on a pu voir l’annonce d’une feature très intéressante : le chiffrement end-to-end des messages WAMP. Ça, c’est chouette. C’est pas encore implémenté, mais ça veut dire que la prochaine release, vous pourrez probablement envoyer des messages à travers le serveur WAMP sans que celui-ci puisse les lire.

8 thoughts on “Nouvelle release de crossbar: historique des events et crypto

  • albert

    La syntaxe :

    async def onJoin(self, details):

    je m’y ferai jamais…Python ça commence à sentir le bricolage et la rustine…

  • Krypted

    Ah si vous saviez comme je l’attends ce fameux article sur l’authentification!

    Par ailleurs, il me semble que dans le dernier bloc de code, from os import environ n’est pas nécessaire.

  • Nasjo

    Curieux, j’ai maintenant une erreur avec mon projet Django lors du lancement de crossbar. Pourtant, je n’ai rien changé d’autre que la version. Depuis 0.11.2 vers la 0.12.1

    WSGI app module ‘project.wsgi’ import failed: No module named django …

    Sais tu s’il y a quelque chose de nouveau dans les routeurs ?

    Je vais creuser ça.

    Merci.

  • Nasjo

    Ah, et comme @Krypted, je suis aussi super impatient de lire ce futur merveilleux post sur l’auth :)

  • Sam Post author

    J’ai pas checké avec django dernièrement, sorry. Le post sur l’auth est dans les backs, mais il est gargantuesque alors je traine la savate.

  • walt

    Ca a l’air toujours aussi bien Crossbar, mais malheureusement ça a l’air toujours aussi peu répandu.

    Quand tu tapes ça dans Google, tu retrouves que quelques articles de Sametmax, ou de Tavendo, qui sont tous les deux écrits par la même personne.

    J’ai passé mon temps à apprendre à me servir de technos, non pas en lisant la doc, mais souvent en lisant des exemples d’utilisations via des articles de blog.

    Aujourd’hui on a une boite commerciale qui tient l’évolution du projet, bien que celui ci soit open source.

    Et on a peu d’utilisateurs. En gros si la boite s’écroule, le projet s’écroule aussi (corrigez-moi si je trompe, je parle un peu au ressenti).

    Du coup je suis vraiment partagé à investir mon temps dans une techno qui a l’air vraiment géniale, mais avec aucune sécurité quand à l’avenir. Je préfère à la limite investir le peu de temps dont je dispose sur une techno un peu moins bien, quitte à ce que ça puisse me servir plus longtemps.

    D’ailleurs, le projet ayant l’air vraiment sympa, une idée de pourquoi la mayo a du mal à prendre auprès des utilisateurs ? Problème de com ? Problème de moyens ?

  • Sam Post author

    Problème de com mais aussi de portée. Le projet reste assez bas niveau. Il manque un framework qui permette de l’utiliser facilement.

Comments are closed.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.