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

Langage PHP Discussion :

Fonction system() ; Exécution trop longue -> timeout


Sujet :

Langage PHP

  1. #1
    Membre confirmé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Points : 486
    Points
    486
    Par défaut Fonction system() ; Exécution trop longue -> timeout
    Bonjour,
    je bosse sur une application chargée de gérer des fichiers sur un serveur.
    Pour cela, l'application en PHP propose une interface utilisateur qui lance des scripts shells sur le serveur avec la commande system :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     system("ma commande unix");
    Ces opérations peuvent durer longtemps et provoquent un timeout (la page arrête de charger) et les instructions suivantes ne sont pas traitées.

    Comment est ce que je peux faire pour palier ce problème ?

    merci d'avance.
    ben

  2. #2
    Membre éprouvé Avatar de Marc3001
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    829
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 829
    Points : 1 275
    Points
    1 275
    Par défaut
    Modifie la valeur max_execution_time définie dans le php.ini.

  3. #3
    Membre confirmé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Points : 486
    Points
    486
    Par défaut
    Je suis pas root et je voulais éviter de toucher aux valeur de la conf ?
    Est ce la seule solution ?

    J'ai également essayé :
    mais sans effet.

    merci

  4. #4
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2010
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 144
    Points : 241
    Points
    241
    Par défaut
    Si l’exécution du script ne retourne rien de particulier il est aussi possible de lancer la commande en arrière plan (avec "nohup"). Dans l'idéal on crée un fichier vide au lancement de la commande, et on le détruit à la fin de l’exécution, comme ça le script php peut savoir où il en est.

  5. #5
    Membre éprouvé Avatar de Marc3001
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    829
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 829
    Points : 1 275
    Points
    1 275
    Par défaut
    Lu dans la doc PHP.

    Notez que set_time_limit() n'a pas d'effet lorsque PHP fonctionne en mode safe mode. Il n'y a pas d'autre solution que de changer de mode, ou de modifier la durée maximale d'exécution dans le php.ini.
    Récupères-tu la sortie de ton script?

    Il faudra peut-être revoir la manière dont tu lances ta commande pour ne pas attendre la fin de celle-ci pour finir le traitement php.
    Après en Ajax tu pourrais récupérer le statut et éventuellement la sortie voire les logs de ta commande.

  6. #6
    Membre confirmé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Points : 486
    Points
    486
    Par défaut
    oui le serveur tourne en mode safe, donc effectivement set_time_limit ne sert à rien et en plus ça n'aurait pas fonctionné car j'utilise un appel externe avec system().

    Actuellement, le script shell, qui est executé via system(), produit un fichier de log, en fonction des valeurs contenues dans ce fichier de log, l'appli va effectuer des opérations en bas de données.

    J'aurais besoin d'attendre la fin de l’exécution du script.

  7. #7
    Membre éprouvé Avatar de Marc3001
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    829
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 829
    Points : 1 275
    Points
    1 275
    Par défaut
    Citation Envoyé par ben.IT Voir le message
    en plus ça n'aurait pas fonctionné car j'utilise un appel externe avec system().
    Si tu avais pu utiliser set_time_limit, cela aurait fonctionné.

    Là tu es bloqué si tu ne veux pas modifier le php.ini, tu ne peux pas augmenter le timeout des scripts php.

    Il ne te reste plus qu'à faire comme je te l'ai expliqué dans mon post précédent.

  8. #8
    Membre confirmé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Points : 486
    Points
    486
    Par défaut
    Citation Envoyé par Marc3001 Voir le message
    Si tu avais pu utiliser set_time_limit, cela aurait fonctionné.
    La fonction set_time_limit et la directive de configuration max_execution_time n'affectent que le temps d'exécution du script lui-même. Tout temps passé en dehors du script, comme un appel système utilisant system , des opérations sur les flux, les requêtes sur base de données, etc. n'est pas pris en compte lors du calcul de la durée maximale d'exécution du script.
    Il semble bien que je sois bloqué ...

  9. #9
    Membre expérimenté Avatar de nathieb
    Homme Profil pro
    DevOps
    Inscrit en
    Mai 2004
    Messages
    1 058
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : DevOps
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 058
    Points : 1 532
    Points
    1 532
    Par défaut Ajax
    Bonjour,

    D'accord avec le dernier post Ajax est la solution.
    Je l'utilise abondamment sur le lancement de procédures stockés en base.
    Le process se détache. Pour le contrôle, après fichier de log
    ou table

    Olivier

  10. #10
    Membre confirmé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Points : 486
    Points
    486
    Par défaut
    ok super merci pour vos réponses, le hic est que je ne connais vraiment pas bien ajax ... mais je ne vois pas d'autres solutions...
    Si vous avez des conseils ou des exemples, je suis preneur...
    merci d'avance,
    ben

  11. #11
    Membre expérimenté Avatar de nathieb
    Homme Profil pro
    DevOps
    Inscrit en
    Mai 2004
    Messages
    1 058
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : DevOps
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 058
    Points : 1 532
    Points
    1 532
    Par défaut bibliothèque
    Bonjour,

    Regarde du côté de prototype ou Jquery

    simple efficace, pas la peine de réinventer la roue.

    Olivier

  12. #12
    Membre confirmé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Points : 486
    Points
    486
    Par défaut
    ok, je regarde du coté AJAX et JQUERY pour lancer mon script de façon asynchrone. Est ce que tu peux m'orienter vers une méthode pour executer mon script de façon asynchrone ? Je suis en train de chercher mais je ne suis vraiment pas familier avec ces technos ...

    merci d'avance,
    ben

  13. #13
    Membre expérimenté Avatar de nathieb
    Homme Profil pro
    DevOps
    Inscrit en
    Mai 2004
    Messages
    1 058
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : DevOps
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 058
    Points : 1 532
    Points
    1 532
    Par défaut Ajax et process
    Bonjour,

    Tu peux détacher un process de son père, cela dépend de ta plateforme.
    Comme tu es sur une plateforme digne, unix ou linux
    il suffit d'utiliser, un script de cette forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    function lanceProcess($filename, $options=''){
             exec(PHP_PATH_BIN . " -f  {$filename} {$options} >> /dev/null & ");
    }
    C'est le >> /dev/null & qui detache le process
    Après tu peux améliorer, car dans mon cas je redirige la sortie
    standard vers rien
    0 : STDIN
    1: STDOUT
    2: STDERR
    ces notions sont des notions bash.
    ce qui fait que tu peux faire un log des erreurs

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    exec(PHP_PATH_BIN . " -f  {$filename} {$options} &> execution.log & ");
    Ce cas fonctionne sans Ajax.
    Il suffit que tu appelles la commande

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <?php
    require_once 'malibquitueduprocessdelamort.php';
     
    ....
    lanceProcess('commande','mesoptions');
    ...
    Olivier

  14. #14
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2010
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 144
    Points : 241
    Points
    241
    Par défaut
    Attention cependant avec le "&" en bash, la commande s’exécute bien en arrière plan mais n'est pas détachée. Par exemple si la console est fermée avant la fin de l’exécution alors elle sera interrompu. Il est possible que le problème se pose à la fin de l’exécution du script PHP ?

    Le préfixe "nohup" permet lui de détacher réellement le process.

  15. #15
    Membre expérimenté Avatar de nathieb
    Homme Profil pro
    DevOps
    Inscrit en
    Mai 2004
    Messages
    1 058
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : DevOps
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 058
    Points : 1 532
    Points
    1 532
    Par défaut exact
    Bonjour,

    Effectivement, oublié le détail, nohup est le meilleur

    Olivier

  16. #16
    Membre confirmé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Points : 486
    Points
    486
    Par défaut
    merci pour vos réponses,

    nohup permet bien, en shell, de détacher un process du terminal ... mais dans cas ça ne résout pas mon problème : à savoir que l'instruction doit être traitée avant de pouvoir continuer à traiter les autres instructions PHP.

    Dans mon cas,

    soit le fichier script.sh :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #!/bin/bash
    echo 'start'
    for i in {1..1000}
    do
      echo $i
      sleep 1
    done
    echo 'end'

    et le fichier index.php :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <?php
    echo 'begining of script..' ;
    exec("nohup /tmp/script.sh &") ;
    echo 'end  of script..' ;
    ?>

    Je dois attendre 1000 secondes avant de pouvoir afficher la page et c'est là que je rencontre le timeout.

    Dans mon cas, le script ne fait pas un "sleep 1000" mais un traitement qui peut effectivement durer très longtemps.

    J'ai pu voir un problème similaire ici



    Any idea ?
    merci d'avance,
    ben

  17. #17
    Membre expérimenté Avatar de nathieb
    Homme Profil pro
    DevOps
    Inscrit en
    Mai 2004
    Messages
    1 058
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : DevOps
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 058
    Points : 1 532
    Points
    1 532
    Par défaut The solution
    Bonjour,

    En fait je crois avoir trouvé la piste de la solution

    int pcntl_fork ( void )

    Voir la documentation PHP

    http://php.net/manual/fr/function.pcntl-fork.php
    Il faut comprendre par contre, la notion de processus père et fils, ainsi que la notion de contexte d'un programme.


    Olivier

  18. #18
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2010
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 144
    Points : 241
    Points
    241
    Par défaut
    Dans le script bash :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #!/bin/bash
    touch /tmp/toto
    ...
    # script
    ...
    rm /tmp/toto
    Et dans le script PHP :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <?php
    if (file_exists('/tmp/toto')) {
        exit('Waiting...');
    }
    .....
    ?>
    Tant que le fichier /tmp/toto existe tu bloques les actions sur ton interface web. Plus de problème de timeout.

Discussions similaires

  1. Exécution trop longue
    Par christouphh dans le forum Requêtes
    Réponses: 2
    Dernier message: 10/04/2013, 17h53
  2. Réponses: 3
    Dernier message: 10/03/2007, 17h59
  3. Exécution trop longue d'une requête
    Par lodan dans le forum Requêtes
    Réponses: 5
    Dernier message: 13/10/2006, 15h34
  4. CGI exécution trop longue
    Par crochepatte dans le forum Web
    Réponses: 6
    Dernier message: 23/08/2006, 15h11
  5. CGI exécution trop longue
    Par crochepatte dans le forum Apache
    Réponses: 3
    Dernier message: 18/08/2006, 15h02

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