Skywalker13

Diary of an ex-GeeXboX developer


Le support des "grabbers" dans la Valhalla ~ đŸ‡«đŸ‡·

Posted at — Aug 11, 2009

Les feuilles d’Yggdrasil ne sont plus si inaccessibles pour les braves de la Valhalla. Les “grabbers” auraient pu s’appeler Heidrun mais on se contentera d’un nom plus technique.

Les “grabbers” sont donc enfin supportĂ©s dans libvalhalla. Il y a encore du travail avant de pouvoir les utiliser correctement depuis Enna, mais l’essentiel est lĂ . Pour ceux qui n’ont aucune idĂ©e de ce qui se cache derriĂšre ce mot barbare “grabber”, on pourrait le dĂ©finir simplement comme Ă©tant une maniĂšre de s’accaparer (si on traduit directement du mot anglais) ou alors de rĂ©cupĂ©rer des donnĂ©es depuis des moyens extĂ©rieurs. Par exemple, libvalhalla peut rĂ©cupĂ©rer des mĂ©ta-donnĂ©es provenant directement des fichiers scannĂ©s, Ă  l’aide d’FFmpeg (le parser). Mais si on dĂ©sire retrouver la couverture CD/DVD il n’Ă©tait pas possible de le faire jusqu’ici. C’est lĂ  qu’intervient le “grabber” tel que celui pour Amazon. On peut imaginer plein d’autres types de “grabbers”, mais celui d’Amazon est le seul portĂ© sous Valhalla au moment oĂč j’Ă©cris ce billet et il permet de “rapatrier” les couvertures CD/DVD.

Architecture

L’architecture de la bibliothĂšque Ă  Ă©tĂ© profondĂ©ment changĂ©e. Trois nouveaux threads ont fait leur apparition et sont visibles dans l’image ci-dessous en tant que “Dispatcher”, “Grabber” et “Downloader”.

L’image correspond au code, nĂ©anmoins elle est un petit peu simplifiĂ©e afin d’ĂȘtre suffisamment lisible et comprĂ©hensible. Le Dispatcher peut ĂȘtre vu comme un switch rĂ©seau. Son but et d’ĂȘtre trĂšs rĂ©actif (il ne fait donc pas grand chose) et de transmettre les “paquets” au bon endroit en fonction de l’Ă©tat de celui-ci. Un “paquet” est une analogie au rĂ©seau, mais finalement dans le cas de libvalhalla, ce n’est rien de plus qu’une structure qui dĂ©fini un fichier.

Afin de bien comprendre l’architecture, je vais dĂ©tailler le chemin effectuĂ© par un paquet. Lorsque le scanner trouve un fichier sur le disque, il “l’empacte” et le transmet au DBManager. Le DBManager va interroger la base de donnĂ©e pour savoir si ce fichier existe dĂ©jĂ , si oui il vĂ©rifie la date de derniĂšre modification et ignore ce paquet si cette date n’a pas changĂ©e, autrement (ou si le fichier n’existe pas dans la base), il transmet le paquet au Dispatcher. Un paquet doit suivre 4 Ă©tapes avant d’ĂȘtre dĂ©truit.

Le processus pour un paquet se résume donc en :

Scanner -> DBManager -> Dispatcher -> Parser -> Dispatcher -> Grabber -> Dispatcher -> Downloader -> Dispatcher -> DBManager -> Scanner.

Ce qui est faux en rĂ©alitĂ©, mais l’idĂ©e est correcte. L’intĂ©rĂȘt de prĂ©senter le processus aussi simplement est uniquement lĂ  pour permettre de comprendre par la suite comment valhalla fonctionne. Si un paquet suivrait vraiment le processus ci-dessus, le systĂšme serait extrĂȘmement lent (j’exagĂšre peut ĂȘtre sur le mot “extrĂȘme”) mais il faut garder en tĂȘte que travailler avec des grabbers ça ne peut que ralentir, surtout s’il y a beaucoup de grabbers et s’ils font des accĂšs sur internet.

Comme un pipeline

Si le Dispatcher, le Parser, le Grabber et le Downloader sont sur des threads diffĂ©rents ce n’est pas juste pour pouvoir traiter plusieurs paquets en parallĂšles, mais aussi pour pouvoir traiter un mĂȘme paquet Ă  plusieurs endroits en mĂȘme temps. L’idĂ©e est donc de rĂ©cupĂ©rer les donnĂ©es “parsĂ©es” et “grabbĂ©es” aussi vite que possible dans la base de donnĂ©e. Ainsi mĂȘme si un paquet n’a pas finit de suivre toutes les Ă©tapes du processus, il est qu’en mĂȘme possible d’aller chercher les informations dans la base de donnĂ©es.

Pour ceux qui connaissent un peu les architectures des processeurs, ils connaissent Ă©galement la reprĂ©sentation en pipeline du cycle d’exĂ©cution des instructions. J’ai vais donc expliquer le systĂšme par un dessin selon ce principe.

Ce pipeline présente 4 fichiers traités par deux parsers parallélisés. Il y a chaque fois deux grabbers en série pour chaque fichier, avec un downloader à la fin du processus.

Les tĂąches des threads de Valhalla fonctionnent en tant que FIFO (Ă  ne pas confondre avec l’ordonnanceur du noyau). Le premier arrivĂ© est donc le premier servi. Chaque fichier de ce pipeline peut ĂȘtre sĂ©parĂ© en deux lignes. C’est ce qui arrive lorsqu’un grabber est en marche et que des mĂ©ta-donnĂ©es doivent ĂȘtre sauvĂ©es dans la base de donnĂ©e. C’est cela qui permet d’avoir un temps de rĂ©action intĂ©ressant. Il est inutile d’attendre que le processus soit terminĂ© pour avoir les mĂ©ta-donnĂ©es. Par exemple avec le “FILE 0”, le Scanner (jaune) transmet le paquet au DBManager (rose pĂąle), qui va le transmettre au Dispatcher (gris) afin d’ĂȘtre “parsĂ©” (rose). Puis le paquet revient au Dispatcher et se voit transfĂ©rĂ© dans deux threads, le grabber (vert) et le DBManager. A ce moment lĂ  il se passe deux choses, le DBManager va insĂ©rer les mĂ©ta-donnĂ©es du Parser dans la base de donnĂ©e et en mĂȘme temps le grabber va commencer Ă  traiter les nouvelles mĂ©ta-donnĂ©es. Puis au “grabbing” suivant, c’est les mĂ©ta-donnĂ©es du grabber prĂ©cĂ©dent qui sont sauvĂ©es quand le deuxiĂšme grabber s’apprĂȘte Ă  traiter les nouvelles mĂ©ta-donnĂ©es. Au final c’est lors de l’Ă©tape du downloading que les derniĂšres mĂ©ta-donnĂ©es sont sauvĂ©es. En rĂ©sumĂ©, chaque case DBManager (de demi-hauteur) correspond Ă  une insertion dans la base de donnĂ©e. Dans le cadre de cet exemple, il y a donc trois insertions par fichier (le parser + les deux grabbers).

J’ai omis quelques informations sinon cet article serait 5 fois plus long.

Il faut Ă©galement prendre le diagramme avec des pincettes car il est impossible de prĂ©dire la forme exacte pour plusieurs raisons. Les cases “parser”, “grabber” et “downloader” en particulier sont trĂšs disproportionnĂ©es. Leur temps est une question de plusieurs dizaines de millisecondes Ă  plusieurs secondes. Tout dĂ©pend de la taille des fichiers, du demuxer utilisĂ© par FFmpeg, de la vitesse de votre connexion internet, du temps sur les accĂšs aux disque dur, etc, 
 Le dispatcher se contente de quelques microsecondes, et dans le diagramme il prend autant de temps que le DBManager ce qui est absurde. Au premier abord on pourrait penser qu’il y a beaucoup de trous dans ce pipeline, mais en rĂ©alitĂ© les trous sont bien plus grand que ça si vous considĂ©rez qu’un parser prend 3 secondes pour un fichier. NĂ©anmoins ce n’est pas du tout un problĂšme (d’ailleurs s’il n’y avait pas de trous alors tous vos CPU seraient constamment Ă  100%; il ne faut pas oublier non plus que dans certaines Ă©tapes il y a des temps morts tel que les accĂšs au disque dur et sur internet).

Si vous regardez bien le diagramme, vous voyez des trous importants aprĂšs les Ă©tapes “parser”. En fait, le scan du disque, le parsing et l’insertion des mĂ©ta-donnĂ©es des parsers vont se faire trĂšs vite. A la mĂȘme vitesse qu’avant l’ajout des grabbers dans Valhalla. Les grabbers ont aucun impacte sur les parsers car ils sont exĂ©cutĂ©s aprĂšs eux. Ce n’est pas plus compliquĂ© que ça.

Il faut Ă©galement interprĂ©ter ce diagramme d’un point de vue plus large. Imaginez le avec plus de 100 lignes (ou plus), ce qui peut arriver sans problĂšme lorsqu’un scanner passe sur un de vos dossiers de musique. Cela donnerait visuellement tous les parsers qui descendraient Ă  gauche en un escalier serrĂ©, et les grabbers seraient parsemĂ©s (avec des trous importants dans toutes les lignes). NĂ©anmoins il peut y avoir des grabbers non utilisĂ©s par certains fichiers, voir mĂȘme aucun grabber, ce qui complique fortement le diagramme.

Quelques précisions

VoilĂ , je n’ai pas la motivation d’en dire plus aujourd’hui, rien que de dessiner le pipeline ça m’a pris pas mal de temps. Je reviendrais donc sur certains aspects dans un prochain billet.

A bientĂŽt,
Mathieu SCHROETER