Probleme avec l'AUTOFLUSH !!!

Probleme avec l'AUTOFLUSH !!! - Perl - Programmation

Marsh Posté le 09-06-2005 à 16:35:10    

Bonjour j'ai un souci avec l'autoflush, je vais essayer d'etre le plus clair possible:  
 
j'ai 2 script Perl, l'un est un script faisant des requetes SNMP en affichant des informations sur le déroulement de l'opération (appelons le script A)et l'autre est un simple script qui s'occupe d'afficher les logos communs à plusieurs pages et quelques mise en forme (appelons le script B). Le problème c'est que j'ai remarqué que l'autoflush ( cad qu'on force les sorties à ne pas etre stocké en mémoire tampon (force l'affichage des PRINT en gros)) ne fonctionne pas si on ouvre une balise dans le script A puis qu'on revient au script B qui appelle le script A pour fermer cette balise.  
 
Je la refais avec un exemple:
 
le script B est appelé grâce au navigateur, il ouvre une balise <HTML> puis appelle la fonction haut() du script A qui ouvre une balise <TABLE>  puis relaisse la main au script B qui à la fin va appelé une fonction bas() du script A pour fermer la balise </TABLE>, ...
 
Dans ce cas là l'autoflush ne fonctionne pas et j'ai essayé de rajouté "$| = 1;" à mon module A mais rien à faire les PRINT sont bufferisés pour etre affiché tout à la fin  :pt1cable:  
 
 
Je précise que j'utilise ActivePerl 5.8 et que la ligne "$| = 1;" est bien présente tout en haut de mon script B !!!
Je ne montre pas le code des scripts car il sont assez gros !
 
Si quelqu'un a l'ombre d'une idée pour que ça puisse m'afficher mes PRINT tout au long de l'exécution SVP...

Reply

Marsh Posté le 09-06-2005 à 16:35:10   

Reply

Marsh Posté le 09-06-2005 à 16:38:20    

comment tu fais interagire tes scripts?

Reply

Marsh Posté le 09-06-2005 à 16:57:54    

Pourquoi ne pas avoir créé un script + un module ?
 
Cela aurait été plus simple à gérer.

Reply

Marsh Posté le 09-06-2005 à 17:19:03    

En fait le script B c'est un script et le script A c'est un module donc qui commence par "package" et avec 2 fonctions.
 
Pour faire simple ça donne:
 
script B:

Code :
  1. #!C:\perl\bin\perl.exe -w
  2. print "Content-type: text/html\n\n";
  3. print "<HTML>";
  4. $| = 1;                       # oblige perl a faire un flush après chaque output
  5. forme::haut();
  6. ...
  7. ...
  8. ...
  9. forme::bas();
  10. print "</HTML>";


 
script A:

Code :
  1. package forme;
  2. sub haut{
  3. print "<TABLE>";
  4. print "<TR>";
  5. ...
  6. ...
  7. return 0;
  8. }
  9. sub bas{
  10. print "</TR>";
  11. print "</TABLE>";
  12. print "</BODY>";
  13. return 0;
  14. }


 
Jsais pas si c'est plus clair. Au passage il s'agit d'un code que je reprend et le gars qui a pondu ce soft a pondu une trentaine de script sans jamais fermer les balises <BODY> mais apparement ça fonctionnait qd meme :pt1cable:  
Bref je voudrais vraiment que ça AUTOFLUSH  :D

Reply

Marsh Posté le 09-06-2005 à 17:22:30    

Rien à voir avec ton problème d'autoflush, mais tu devrais jeter un oeil sur le module CGI :
http://search.cpan.org/~jhi/perl-5.8.0/lib/CGI.pm
 :o  
 


Message édité par Elmoricq le 09-06-2005 à 17:23:44
Reply

Marsh Posté le 09-06-2005 à 17:26:43    

C'est-à-dire rien à voir ???
J'ai jeté un oeil sur le lien mais jsais pas trop ou chercher vu que tu me dis que c'est pas un problème d'autoflush !!!

Reply

Marsh Posté le 09-06-2005 à 17:31:07    

Ca n'a rien à voir avec ton souci dans la mesure où intégrer ce module ne va pas résoudre ton problème d'autoflush.
Néanmoins, jette un oeil sur ce module, il a tout ce qu'il faut pour créer des CGI très facilement, et beaucoup plus proprement. Ne serait-ce que pour la récupération des paramètres.  

Quant à ton problème, je m'étonne qu'il n'y ait pas de "use forme;" au début de ton script B, et qu'il n'y ait pas de module Exporter ni d'exportation de fonctions dans ton module. C'est normal ?

 
EDIT : ignorer le dernier paragraphe, je viens de comprendre... j'suis fatigué.


Message édité par Elmoricq le 09-06-2005 à 17:32:46
Reply

Marsh Posté le 09-06-2005 à 17:31:34    

hmm des packages avec des noms en minuscultes! pas tres beau ca. normalement les noms en misuscules sont reservés au pragmas.
 
bon, pour ton pobleme je sais pas si $| serait pas scopé sur le fichier...
essai toujours de mettre un $|=1 dans ton package, mais franchement ca m'etonnerais que ca change qqchose (c'est global normalement, à mon que je me fourre un doigt dans le nerf optique)
 
le plus propre ce serait que Forme renvoi une chine et que tu la print dans ton main:
 
print Forme::haut();
 
...
 
haut{"<table><tr>....

Reply

Marsh Posté le 09-06-2005 à 17:34:35    

"EDIT : ignorer le dernier paragraphe, je viens de comprendre... j'suis fatigué."
 
ben ouai mais t'as raison: il manque tout de meme le use.

Reply

Marsh Posté le 09-06-2005 à 18:59:54    

il me semble qu'il y a un "use "
mais jvais vérifier ...
j'ai déja essayé de mettre un $|=1 dans le package mais effectivement ça ne change rien.
sinon jvais voir ce que je peux faire avec le "print Forme::haut(); "
 
Merci pour vos idées jvous tiens informer ;)

Reply

Marsh Posté le 09-06-2005 à 18:59:54   

Reply

Marsh Posté le 10-06-2005 à 10:21:25    

pospos a écrit :

hmm des packages avec des noms en minuscultes! pas tres beau ca. normalement les noms en misuscules sont reservés au pragmas.
 
bon, pour ton pobleme je sais pas si $| serait pas scopé sur le fichier...
essai toujours de mettre un $|=1 dans ton package, mais franchement ca m'etonnerais que ca change qqchose (c'est global normalement, à mon que je me fourre un doigt dans le nerf optique)
 
le plus propre ce serait que Forme renvoi une chine et que tu la print dans ton main:
 
print Forme::haut();
 
...
 
haut{"<table><tr>....


 
 
Re j'ai un souci pour tester avec les print ds le main. J'ai transformé sub bas en :

Code :
  1. sub bas{
  2. return "</TR></TABLE></BODY>";
  3. }


 
mais jsais pas comment faire la meme chose avec sub haut qui contient des open etc...:
 

Code :
  1. sub haut{
  2. open (FIC, "<../confgal.txt" );
  3. while (defined ($l=<FIC> ))
  4. {
  5. chomp $l;
  6. $nom=$l;
  7. last;
  8. }
  9. @hop=split(//,$nom);
  10. $reste=splice(@hop, 0, 1);
  11. if ($reste eq "<" || $reste eq ">" ) {$nom=join('',@hop);}
  12. @hop=split(/\\/,$nom);
  13. ($alias,@hop)=split(/\.txt/,$hop[@hop-1]);
  14. print "<TABLE>";
  15. print "<TR>";
  16. ...
  17. ...
  18. return 0;
  19. }


 
Savez vous comment je peux faire SVP ???
 

Reply

Marsh Posté le 10-06-2005 à 10:41:06    

Avec des variables. Mais dis-nous ce que tu cherches à faire parce que j'ai du mal à saisir.
 
Quelques remarques :

  • pense à indenter le code, la lisibilité d'un programme est primordiale ;


  • détecte les éventuelles erreurs, pour éviter des plantages difficiles à repérer ;


  • une boucle "while" avec un last sans condition ne sert à rien, autant ne mettre aucune boucle ;


  • utilise "use strict;" pour t'obliger à écrire du code propre, ça évite que la permissivité du PERL te cache des erreurs qui peuvent être galères à trouver ;


  • utilise des noms de variables explicites, toujours dans un souci de lisibilité. Celui qui passera derrière toi 6 mois plus tard te dira merci ;


  • commente ton code lorsque celui-ci n'est pas trivial (ne prends pas exemple sur ce que j'ai mis ici, c'est pour t'expliquer certaines parties du code, il ne devrait pas y avoir autant de commentaires pour un tel code) ;


  • les tags HTML devraient toujours être en minuscules ;


  • réfléchis, avant de coder, à la manière de procéder, pour programmer de manière logique et simple.


Code :
  1. sub haut
  2. {
  3.    open (FIC, "<../confgal.txt" )
  4.       or die "Echec ouverture 'confgal.txt' : $!";
  5.    my $ligne = <FIC>;
  6.    chomp $ligne;
  7.    # Plutôt que d'extraire le premier caractère, il est plus
  8.    # simple de tester si $ligne débute par '<' ou '>'
  9.    # Voici une expression régulière qui va faire ça
  10.    my $nom = "";
  11.    if ( $ligne =~ /^</ or $ligne =~ /^>/ )
  12.    {
  13.       # si j'ai compris ton raisonnement, on a ici une ligne de type:
  14.       # <nom_de_fichier.txt (ou ">nom_de_fichier.txt" )
  15.       # on va dégager le premier caractère
  16.       ($nom = $ligne) =~ s/^.(.*?)$/$1/;
  17.    }
  18.    else
  19.    {
  20.       # sinon, extraire "nom_de_fichier.txt"
  21.       # Toujours avec une expression régulière... c'est simple
  22.       # lisible, et évite les split() alambiqués
  23.       ($nom = $ligne) =~ s/^.*\\(.*?)$/$1/;
  24.    }
  25.    # A partir de maintenant, on peut gérer ce qu'on veut avec "$nom"
  26.    # Admettons pour l'exemple qu'on souhaite l'afficher avant le début
  27.    # du tableau, grace à la chaîne que cette sub va retourner
  28.    my $retour = "";
  29.    $retour = "Nom du fichier : $nom<br>\n";
  30.    $retour .= "<table>\n";
  31.    $retour .= "<tr>\n";
  32.    # Ne pas oublier de fermer le fichier
  33.    close FIC;
  34.    return $retour;
  35. }


 
 
Avec ceci, il te suffit d'appeler la sub avec :
 

Code :
  1. my $chaine = haut();


 
ou encore :
 

Code :
  1. print haut();


 
 
Pose des questions si tu ne comprends pas.


Message édité par Elmoricq le 10-06-2005 à 10:47:38
Reply

Marsh Posté le 10-06-2005 à 10:59:38    

Elmoricq a écrit :

Avec des variables. Mais dis-nous ce que tu cherches à faire parce que j'ai du mal à saisir.
 
Quelques remarques :

  • pense à indenter le code, la lisibilité d'un programme est primordiale ;


  • détecte les éventuelles erreurs, pour éviter des plantages difficiles à repérer ;


  • une boucle "while" avec un last sans condition ne sert à rien, autant ne mettre aucune boucle ;


  • utilise "use strict;" pour t'obliger à écrire du code propre, ça évite que la permissivité du PERL te cache des erreurs qui peuvent être galères à trouver ;


  • utilise des noms de variables explicites, toujours dans un souci de lisibilité. Celui qui passera derrière toi 6 mois plus tard te dira merci ;


  • commente ton code lorsque celui-ci n'est pas trivial (ne prends pas exemple sur ce que j'ai mis ici, c'est pour t'expliquer certaines parties du code, il ne devrait pas y avoir autant de commentaires pour un tel code) ;


  • les tags HTML devraient toujours être en minuscules ;


  • réfléchis, avant de coder, à la manière de procéder, pour programmer de manière logique et simple.


 
Pose des questions si tu ne comprends pas.


 
 
LOL comme je l'ai dis plus haut :

Citation :

Au passage il s'agit d'un code que je reprend et le gars qui a pondu ce soft a pondu une trentaine de script sans jamais fermer les balises <BODY> mais apparement ça fonctionnait qd meme :pt1cable:


Perso je suis tout à fait d'accord avec toi seulement je ne peux pas me permettre de tout corriger car il y a environ 38 scripts à reprendre   :non:  
 
Sinon ce que je cherche à faire c'est que mes prints s'affichent au fur et à mesure de l'execution du script qui fait des requetes SNMP... et non qu'ils soient bufferisé pour etre affiché à la fin d'un coup !
 
En fait en faisant quelques test j'en conclus que l'instruction "$| = 1;" n'a pas d'effet si on ouvre une balise dans une fonction et qu'on ne la referme pas dedans...
 
 
Si je suis pas clair n'hesitez pas à me le dire :)

Reply

Marsh Posté le 10-06-2005 à 11:06:10    

Gouki19 a écrit :

LOL comme je l'ai dis plus haut :

Citation :

Au passage il s'agit d'un code que je reprend et le gars qui a pondu ce soft a pondu une trentaine de script sans jamais fermer les balises <BODY> mais apparement ça fonctionnait qd meme :pt1cable:



 
Comme tu la dis plus haut :
 

Citation :

Re j'ai un souci pour tester avec les print ds le main. J'ai transformé sub bas en :
<...code...>
mais jsais pas comment faire la meme chose avec sub haut qui contient des open etc...:  


 
Moi je fais que répondre aux questions posées.   :o  
 
 
 
 

Gouki19 a écrit :

En fait en faisant quelques test j'en conclus que l'instruction "$| = 1;" n'a pas d'effet si on ouvre une balise dans une fonction et qu'on ne la referme pas dedans...


 
Rien à voir, PERL se moque de savoir ce qu'il y a dans tes chaînes, et il se contrefiche de savoir si c'est du html, du cobol, de l'hébreu ou des formules mathématiques.
 
Pour forcer un flush, rien ne vaut un bon vieux caractère de retour à la ligne : "\n".
Essaie d'en placer un à la fin du dernier print de chacune de tes fonctions, pour voir.

Reply

Marsh Posté le 10-06-2005 à 11:44:23    

38 script à reprendre c'est pas la mort...

Reply

Marsh Posté le 10-06-2005 à 12:30:31    

hmmm 38 script dont certains font 2000 lignes de codes ...

Reply

Marsh Posté le 10-06-2005 à 12:34:07    

Sinon j'ai tester vos solutions c'est-à-dire que j'ai transformé le code de maniere à ce que les fonctions renvoient une chaîne de caractères et je fais un "print forme::haut();" et "print forme::bas();" et j'ai mis un "\n" à la fin de chacun des derniers print des fonctions. Mais rien à faire ça veut pas les afficher pendant l'exécution... ://

Reply

Marsh Posté le 10-06-2005 à 12:37:18    

Etrange. Je fais ce genre de chose, et tout fonctionne bien chez moi.
Je n'ai qu'un seul $| au début de mon script principal, et des modules.
 
Je ne vois pas où se situe le problème.

Reply

Marsh Posté le 10-06-2005 à 12:43:05    

Oui en effet c'est vraiment strange car comme tu l'as dis normalement PERL se moque de savoir ce qu'il y a dans mes PRINT mais peut etre que ça pose des pb d'affichage pour arranger les différents éléments à afficher en attendant la fermeture de balises... enfin jsais pas du tout c'est vraiment bizarre sur ce coup là !!!  :(

Reply

Marsh Posté le 10-06-2005 à 13:10:39    

mais en fait il se manifest comment ton probleme?
esque ca ne serait pas plutot ton navigateur qui refuserais d'afficher la page? a cause de balises mal positionnées peut etre?
 
essai ca:
tu te met en ligne de commande et tu tappe:
GET http://ton url
 
ca va afficher le source html tel que le recoi ton navigateur

Reply

Marsh Posté le 10-06-2005 à 13:37:41    

Bonne remarque pospos car tu m'as donné l'idée de tester avec un 2eme navigateur (Firefox) et en fait le comportement est différent qu'avec ce vieux IE: avec firefox les print s'affiche durant l'execution de façon un peu irréguliere mais ça fonctionne. :)
 
Sinon jvais maintenant essayer de voir le source HTML que reçois le navigateur.
 
Jvous tiens au courant ;)

Reply

Marsh Posté le 10-06-2005 à 16:24:55    

Alors j'ai testé avec Netscape et Opéra et il s'avère qu'avec Opéra il n'y a aucun souci, les PRINT s'affiche au fur et à mesure que le script s'exécute :) D'ailleurs dans Opéra il y a meme une option (dans Outils>Preferences>Fenetres>Chargement) qui permet d'actualiser le chargement de la fenetre toutes les n secondes et ça joue sur le rendu...
Dans Netscape j'ai trouver une option qui Améliore les performances (Edition>Avancee>Activer Quick Launch) et ça affiche les PRINT en bloc mais pas réellement au fur et à mesure...
Bref certains aspect restent suspect...

Reply

Marsh Posté le 10-06-2005 à 16:25:59    

Merci encore pour votre aide ;)

Reply

Marsh Posté le 10-06-2005 à 18:28:27    

ca doit etre pasque le html généré est foireux => certinas navigateurs le tolere, d'autre pas
 
donc tu va avoir le plaisir de parcourir les 38*2000 lignes de tes script à la recherche du tag à fermer...
bonne chance

Reply

Marsh Posté le 15-06-2005 à 09:42:09    

Finalement j'ai trouvé. En fait c'est juste une histoire de balise <TD></TD> qui posait problème. c'est-à-dire que mon tableau qui englobe tous éléments de la page était de la forme: <TABLE><TR><TD></TD></TR></TABLE> et ça posait problème avec IE visiblement. Mon tableau est devenu: <TABLE><TR></TR></TABLE> et ça fonctionne très bien ( plus de pb d'autoflush ) :D
 
Encore merci pour m'avoir répondu ;)

Reply

Marsh Posté le 15-06-2005 à 10:40:17    

Citation :

Mon tableau est devenu: <TABLE><TR></TR></TABLE> et ça fonctionne très bien ( plus de pb d'autoflush )


 
Mais maintenant tu n'as plus de colonne non plus.  [:petrus75]  
 
Ca m'étonne quand même, le comportement que tu constates. Tu as bien un nombre constant de colonnes, ou celui-ci peut-il varier au sein d'une même table, au gré d'éventuels champs vides par exemple ?

Reply

Marsh Posté le 15-06-2005 à 10:53:18    

passe ton html dans un validateur du w3c pour voir si ca merde pas ailleurs :
http://validator.w3.org/

Reply

Marsh Posté le 15-06-2005 à 16:58:01    

oui ça m'etonne le comportement que je constate... :s
 
Je vais suivre ton conseil pospos et passer mon html dans un valideur du w3c ;)

Reply

Marsh Posté le 16-06-2005 à 15:32:01    

pospos a écrit :

passe ton html dans un validateur du w3c pour voir si ca merde pas ailleurs :
http://validator.w3.org/


 
Bon j'ai testé le valideur que tu m'as donné pospos mais il me trouve des erreurs là ou il ne semble pas y en avoir... ou alors j'ai pas capté.
 
Enfin bref apres de multiples tests dans tous les sens je constate que comme l'as évoqué pospos plus haut, les navigateurs n'ont pas tous le meme niveau de tolérance d'ailleurs ils ne respectent pas toutes les normes et standards !!!
 
par exemple je constate ceci:
 
en faisant un truc de la forme:  

Code :
  1. <TABLE>
  2.   <TR>
  3.    <TD>
  4.     <TABLE>
  5.      ...
  6.     </TABLE>
  7.     ...
  8.     ...
  9.    </TD>
  10.   </TR>
  11. </TABLE>

Alors avec IE l'autoflush semble inopérant ( pas d'affichage durant l'execution du script mais seulement à la fin d'un coup)
Avec Opéra ça fonctionne (grâce au chargement de la fenetre qui s'actualise toute les seconde) et firefox c'est quasiment pareil que IE.
 
Quand je fais:

Code :
  1. <TABLE>
  2.   <TR>
  3.    <TABLE>
  4.     ...
  5.    </TABLE>
  6.   </TR>
  7. </TABLE>

Là pas de souci d'autoflush avec IE par contre sous firefox et Opéra la page est décentré verticalement vers le bas c'est-à-dire qu'on a une page blanche et qu'il faut descendre avec la barre de défilement pour voir le contenu de la page (pourtant avec IE ça ne bouge pas, ma page ne présente pas de barre de défilement).
 
Bien entendu j'ai essayé pas mal de choses avec les attributs "valign" des différentes balises, j'ai également remis une balise <TD></TD> mais après mon sous tableau, tenté de ne pas fermé les balises <TR> ou <TD> (leur fermeture étant optionnel), :pt1cable: ... bref il y a toujours un souci soit avec l'autoflush soit l'affichage décalé vers le bas sous firefox et Opéra. Je tourne en rond, un vrai casse-tête   :pt1cable:  
 
J'ai bien vérifié les balises générées et à priori il n'y a pas d'erreur de ce coté là (d'ailleurs le scripte n'en génère pas tant que ça).
 

Reply

Marsh Posté le 16-06-2005 à 15:48:15    

laisse de coté le terme "autoflush", il ne correspond pas au probleme.
 
si tu fait du HTML valide tu peux etre quasi certain qu'il passera partout

Reply

Marsh Posté le 16-06-2005 à 16:16:38    

pospos a écrit :

laisse de coté le terme "autoflush", il ne correspond pas au probleme.
 
si tu fait du HTML valide tu peux etre quasi certain qu'il passera partout


 
+1
Les différents tests ont bien montré que l'autoflush fonctionne.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed