2. Fonctionnement du Crawler
2.1. Fonctionnement du Crawler
– Parcours
Nous avons tout d'abord souhaité adopter un fonctionnement du crawler utilisant les Threads Java. Les principales raisons pour le choix de ce mode de fonctionnement étaient :
Des modifications ont donc été apportées aux classes fournies pour le projet afin de pouvoir implémenter une telle version. Les modifications les plus importantes ont été effectuées sur la classe CrawlerParser.
L’analyse d'une page A se déroule de la manière suivante :
Remarque : Le CrawlerParser connaît à quelle profondeur il se trouve car il est créé en lui indiquant sa profondeur.
On obtient alors une "arborescence" de Thread correspondant à la structure du site analysé. A ce stade l'implémentation, il n'existait pas de relations réelles entre les différents Thread. La structure d'arbre n'existait pas réellement car il n'y a avait aucune notion de père / fils.
Une difficulté a permis d'ajouter
cette relation père / fils. Il est en effet apparu qu'il était
nécessaire d'effectuer un appel à la méthode join() de
Thread sur chaque fils créé afin de connaître la fin d'exécution
du fils. Le Thread père peut alors arrêter son exécution
lorsqu’il a fini d’attendre tous ces Thread fils.
Dans cet exemple, le Thread principal (1) attend la fin de l’exécution de (2) car son fils (3) est terminé. Or (2) est obligé d’attendre la fin de l’exécution de l’un de ces fils. On a donc, dans cet exemple, deux Thread bloqués sur join().
Dans un soucis d'efficacité du programme, il était souhaitable de supprimer les appels à la méthode join(). Cette suppression a été rendue possible grâce à la classe ThreadGroup de java.lang. Cette classe permet de rattacher un Thread à un ThreadGroup et permet un certain nombre d'opérations dont notamment :
L'implémentation du crawler à l'aide de ThreadGroup a donc aussi permis de limiter les attentes, car il n’était plus nécessaire qu’un père attendent la fin de ses fils pour terminer. Grâce à l’implémentation à l’aide des ThreadGroup, un père ajoute ses fils à un ThreadGroup contenant tous ces fils. Ce ThreadGroup est rattaché, lors de sa création au ThreadGroup du père du père (grand-père). On obtient alors une véritable arborescence de ThreadGroup.
2.2. Fonctionnement du Crawler – Insertion
Pour stocker de manière durable
les résultats des analyses des différents CrawlerParser, il a
été décidé de créer une classe uniquement
dédiée à cet usage. Il a été ensuite introduit
une notion de modules complétant la possibilité d’enregistrement
des résultats des différentes analyses.
La procédure suivie lors de la découverte d’un lien est
la suivante. Dans cet exemple, le CrawlerCallbackHandler découvre un
lien et souhaite le faire connaître au reste du programme.
1. Notification d’un
nouveau lien au CrawlerParser dont dépends ce CrawlerCallbackHandler.
2. Le CrawlerParser reçoit une notification d’un nouveau lien car
sa méthode reportNewLink(...) a été appelée.
3. Le CrawlerParser notifie son CrawlerReport qu’il a trouvé un
nouveau lien.
4. Le CrawlerReport prend connaissance du nouveau lien et informe ces différents
modules du nouveau lien trouvé. Chaque module ensuite prend en charge
ce lien comme il le souhaite (insertion dans un fichier, insertion dans une
base de données ou encore incrémentation de statistiques).
Remarque : Tous les différents Thread du programme partage le même CrawlerReport initialisé au lancement du programme. C’est pourquoi toutes les méthodes de rapport (reportNewLink(...), ...) sont déclarées synchronized. L’utilisation de ce mot clé permet de gérer l’accès concurrent à une méthode en interdisant l’accès à une méthode par plusieurs Thread différents en même temps.
Remarque : La liste des modules devant être chargés au démarrage et ajoutés au CrawlerReport est contenue dans le fichier de propriétés du crawler (nom de la propriété : report_modules).
Cette séparation en modules
permet une diversification des possibilités d’enregistrement. Il
est possible, par exemple, de rajouter un module permettant l’insertion
d’un lien dans la base en appliquant l’algorithme Pagerank. On peut
aussi bien imaginer un module permettant le stockage des liens en mémoire
afin de pouvoir recréer la structure du site analysé à
l’écran.