IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Modules Perl Discussion :

AnyEvent::HTTP - crash PERL


Sujet :

Modules Perl

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Octobre 2017
    Messages : 5
    Points : 1
    Points
    1
    Par défaut AnyEvent::HTTP - crash PERL
    Bonjour,

    J'ai plus de 400 pages HTML à parser, mon but est de paralléliser le traitement car j'utiliserai ce script dans une page web plus tard...
    Pour cela j'ai trouvé un code qui utilise anyevent, ça fonctionne très bien si le nombre d'url en entrée n'est pas trop important, mais dans mon cas perl se plante avant d'arriver à la fin de la liste.

    Nom : ScreenShot093.jpg
Affichages : 255
Taille : 42,2 Ko

    J'ai essayé de "découper" l’exécution de mon programme avec un "while", perl plante de la même manière.

    S'agit il d'une saturation mémoire ? Comment y remédier ?

    Précisions :
    Je travail sur un serveur windows 2012 R2, avec perl v5.24.1.

    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    use strict;
    use warnings;
    use AnyEvent;
    use AnyEvent::HTTP;
     
     
    open( FIC, "url.txt");
     my @urls = <FIC>;
    close (FIC);
     
    open( FIC2, ">result.txt")|| die("Probleme ouverture Fichier en entrée !");
    print (FIC2 "Nombre totales d'urls \$#urls : $#urls\n");
     
     
    my $cv = AnyEvent->condvar; #initialisation anyevent
    my $GenCount = 1;
    my $count = 0; #initialisation compteur anti goulet d'étranglement
    my $max = 50;
     
     
    for (1 .. $max) {
       send_url();
    }
    print (FIC2 "Before the event-loop\n");
    print "Before the event-loop\n";
     
    $cv->recv;
     
    print (FIC2 "Finish\n");
    print "Finish\n";
    close (FIC2);
     
    ###########################Fonction########################################
    sub send_url {
    	return if $count >= $max;
     
    	my $url = shift @urls;
    	return if not $url;
    	chomp $url;
    	$count++;
    	print (FIC2 "Start ($count) $url\n");
    	print "Start ($count) $url\n";
    	$cv->begin;
     
    	#http_get $url, sub {
     
    	http_request GET => $url, sub {	
    		my ($body, $hdr) = @_;
    		#print Dumper @_;
    		#print "$body\n";
    		print (FIC2 "$count - $hdr->{URL}\n");
    		print "$hdr->{URL}\n";		
    		my $rc=$hdr->{Status};
    		print "Code retour : $rc\n";
    		if ($body =~ /appliok|appliko/i ) { print "Pattern : $&\n"; print (FIC2 "Pattern : $&\n");} else {print "Pattern : NULL\n"; print (FIC2 "Pattern : NULL\n");}
    		if ($body =~ /(serveur : )(\w+)/i ) { print "Serveur : $2\n"; print (FIC2 "Serveur : $2\n");} else {print "Serveur : NULL\n"; print (FIC2 "Serveur : NULL\n");}
     
    		#print "$hdr->{date}\n";
    		#print "$hdr->{Reason}\n";
     
    		#print "$url received, Size: Status $html\n";
    		print (FIC2 "#############$GenCount##############\n");
    		print "#############$GenCount##############\n";
     
    		$cv->end;
    		$count--;
    		$GenCount ++;
    		send_url();
    	};
     
    	return 1;
    };
    Merci pour votre aide.

  2. #2
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 490
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 490
    Points : 19 534
    Points
    19 534
    Par défaut
    Salut xzefir.

    Le coeur de votre traitement est la fonction "send_url()". L'avez-vous testé avec 1 seul message ?
    J'aurai mis un temporisateur, histoire de ne pas créer un goulot d'étranglement dans la file d'attente de vos message.
    Soit un sleep soit quelque chose d'autre qui permet d'attendre que votre message a bien été envoyé !

    @+

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Octobre 2017
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Artemus24 Voir le message
    Salut xzefir.

    Le coeur de votre traitement est la fonction "send_url()". L'avez-vous testé avec 1 seul message ?
    J'aurai mis un temporisateur, histoire de ne pas créer un goulot d'étranglement dans la file d'attente de vos message.
    Soit un sleep soit quelque chose d'autre qui permet d'attendre que votre message a bien été envoyé !

    @+
    Bonjour Artemus24,
    Merci pour la réponse, mon programme fonctionne si je le test avec 1 ou 100 url en entrée, ça plante à partir de +ou- 400 url.
    Pour tester, j'ai essayé de positionner une tempo dans la boucle "for" et dans la fonction, le script plante de la même manière.

    Je pensais à une accumulation de données qui provoquerai une saturation mémoire, mais comment voir cela ?

  4. #4
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 490
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 490
    Points : 19 534
    Points
    19 534
    Par défaut
    Salut xzefir.

    Citation Envoyé par xzefir
    Je pensais à une accumulation de données qui provoquerai une saturation mémoire, mais comment voir cela ?
    C'est ce à quoi j'ai tout de suite pensé en voyant votre traitement.

    Comment voir cela ? Et bien, dès qu'il y a un plantage, la cause est certainement un "overflow".

    Citation Envoyé par xzefir
    mon programme fonctionne si je le test avec 1 ou 100 url en entrée, ça plante à partir de +ou- 400 url.
    Pourquoi ne pas descendre à 100 url, si cela ne provoque aucun plantage ?
    J'entends un envoi de 100 url, un temporisateur, puis un autre envoi de 100 url et ainsi de suite.

    Citation Envoyé par xzefir
    Pour tester, j'ai essayé de positionner une tempo dans la boucle "for" et dans la fonction, le script plante de la même manière.
    Qu'est-ce que vous envoyez ? Du texte ? des images ? Des pièces jointes ?
    Autrement dit, quel est la volumétrie du message que vous envoyez ?

    Il faut marquer une pause à chaque envoi d'un paquet de message.
    Avez-vous fait correctement cette pause et comment l'avez-vous fait ?

    Si cela est possible, vous pouvez éviter d'envoyer le message à un utilisateur à la fois, mais d'utiliser le "cc" (carbon copy).
    A moins qu'il y a un confidentialité dans vos messages, et vous ne désirez pas faire apparaitre le nom des autres utilisateurs.

    @+

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Octobre 2017
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Salut,
    Mon intérêt dans le fait de paralléliser le téléchargement des pages avec anyevent est de pouvoir tester mes url rapidement. Ce script est intégré dans une page HTML, je voudrais pas que l'utilisateur attende trop longtemps avant d'avoir le résultat. Alors je suis un peu réticent pour le rajout de tempo, j'ai testé avec des tempo juste pour voir si ça arrangeait les choses.

    N'y a t-il pas un moyen de voir ou s'accumulent les données, et éventuellement de purger celles-ci ?

    Il s'agit de page HTML de test plutôt légères.
    Pour la volumétrie les pages font en moyenne 2500 octet pour un total d'environ 900 Ko.

    Je n'envois pas de message, j'écris à l'écran pour le debug et dans un fichier.

    J'essaye de diviser le traitement ... ça plante encore

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
     
    open( FIC, "url.txt")||die("Probleme ouverture Fichier en entrée !");
     my @urls = <FIC>;
    close (FIC);
    open( FIC2, ">result.txt")|| die("Probleme ouverture Fichier en entrée !");
     
    #Calcul du nb de passe pour éviter la saturation mémoire
    my $cpt=0;
    my $i=1;
    my $imax = 10;
    my $urlsmodulo = $#urls%$imax;
    my $urlsmax = ($#urls-$urlsmodulo)/$imax;
    my $urlsmaxi=$urlsmax+$urlsmodulo+1;
     
     
    print (FIC2 "Nombre totales d'urls \$#urls : $#urls\n");
    print (FIC2 "Nombre max : $urlsmax\n");
    print (FIC2 "Modulo : $urlsmodulo\n");
    print (FIC2 "\$urlsmaxi : $urlsmaxi\n");
     
    my $cv = AnyEvent->condvar;
     
    while ( $i <= $imax ) {
    	select(undef, undef, undef, 0.2); #time 0.2 seconde
    	$cv = AnyEvent->condvar;
    		while ( $cpt < $urlsmaxi) {
    			$cv->begin;
    			print ( FIC2 "Before the event-loop\n");
    			my $url=$urls[$cpt];
    			chomp $url;
    			print "Start($cpt) $url\n";
    			print ( FIC2 "Start($cpt) $url\n");
     
     
     
    				http_request GET => $url, sub {	
     
    					my ($body, $hdr) = @_;
     
    					print ( FIC2 "($cpt) $hdr->{URL}\n");
    					my $rc=$hdr->{Status};
     
    					print ( FIC2 "Code retour : $rc\n");
    					if ($body =~ /appliok|appliko/i ) { print ( FIC2 "Pattern : $&\n");} else { print ( FIC2 "Pattern : NULL\n");}
    					if ($body =~ /(serveur : )(\w+)/i ) { print ( FIC2 "Serveur : $2\n");} else { print ( FIC2 "Serveur : NULL\n");}
     
    					print ( FIC2 "############$cpt###############\n");
     
    			$cv->end;
    				};
     
    		$cpt++;
     
    		};
    	$urlsmaxi=$urlsmaxi+$urlsmax;
    	$i++;
    	$cv->recv;
    	print ( FIC2 "Finish($i) \n");
     
     
     
    };
     
    close (FIC2);

  6. #6
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 490
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 490
    Points : 19 534
    Points
    19 534
    Par défaut
    Salut xzefir.

    Désolé de ne pouvoir vous aider plus.
    Si un expert du langage perl passe par ici, il sera plus à même de répondre à ce genre de question.

    En ce qui me concerne, j'ai rencontré le même problème avec la fonction "mail()" lors d'un envoi de masse.
    J'ai résolu en parti mon problème en utilisant le "Carbon Copy" au lieu de faire un message par destinataire.

    @+

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Octobre 2017
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Merci pour ton aide Artemus,
    Si je trouve la solution à mon problème, je la posterais.

    @+

  8. #8
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Bonjour,
    je ne connais pas le module que tu utilises, donc je me trope peut-être lourdement, mais j'ai l'impression que tu lances probablement trop de processus en parallèle.

    Peut-être que ta variable $countne fonctionne pas comme tu le désires. Peux-tu essayer de lancer le programme avec par exemple 100 URL (pour que ça ne plante pas) et en affichant à l'écran ou dans l'un de tes fichiers la valeur de $count, afin de vérifier si elle est incrémentée comme tu le désires (je soupçonne que chaque processus hérite de sa propre copie de $count et que, par conséquent, cette variable ne joue peut-être pas son rôle de limiter le nombre de processus lancés).

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Octobre 2017
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Salut,
    C'est bien ça mon problème, j'arrive pas à limiter le nombre de process en parallèles, dans la première version $count ne fonctionne pas effectivement, il reste toujours au max, je trouve pas pourquoi.

    La deuxième version que j'ai posté, avec le while, je pensais traiter les URL par paquets, mais ça marche pas mieux

  10. #10
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 490
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 490
    Points : 19 534
    Points
    19 534
    Par défaut
    Salut à tous.

    Citation Envoyé par lolo78
    mais j'ai l'impression que tu lances probablement trop de processus en parallèle.
    C'est tout à fait ça. La file d'attente étant limitée à un certain nombre de message, si vous dépassez cette limite, cela provoque un plantage !

    Si vous envoyez un message à la fois, avec un temporisateur, normalement, vous ne devez pas obtenir de goulot d'étranglement.
    Autrement dit, vous envoyez un message et vous atendez que celui-ci soit envoyez avant de répéter la même opération.

    @+

Discussions similaires

  1. Gérer les erreurs http en perl
    Par Olivier Regnier dans le forum Web
    Réponses: 9
    Dernier message: 09/11/2007, 11h22
  2. [web] Requetes HTTP en perl
    Par siemens dans le forum Web
    Réponses: 4
    Dernier message: 13/11/2006, 13h37
  3. Perl.exe crash à chaque appel
    Par Fabien Celaia dans le forum Langage
    Réponses: 4
    Dernier message: 07/06/2006, 08h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo