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

Performance Web Discussion :

Gérer des requêtes d'exports de bdd très longs par le web


Sujet :

Performance Web

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Gérer des requêtes d'exports de bdd très longs par le web
    Bonjour,

    Je développe une application PHP qui interroge une base postgresql de données génétiques. L'application lance des requêtes d'export, elles ont été optimisées avec l'aide un prestataire mais restent très longues (plusieurs minutes).

    Ma question est : comment après choix des paramètres d'export par l'utilisateur, lui rendre la main pour poursuivre sa navigation, pendant que son export est préparé (et transmit plus tard si besoin) ?

    J'ai essayé avec AJAX de gérer mes exports pour que s'ils durent moins d'un certain temps, il soient affichés par le navigateur (sous forme de fichiers excel), sinon, ils sont envoyés par mail. Je suis passé par une requête XMLHttpRequest asynchrone (post via $.ajax) mais si j'arrive à rendre la main à l'utilisateur après un temps défini par le timeout de la requête ajax (pendant que le code d'export PHP termine de s'exécuter), je ne peux plus naviguer tant que la requête SQL n'est pas terminée.

    Ce site confirme que même asynchrones, les requêtes AJAX sont séquentielles. Pourriez vous m'indiquer quelle piste suivre pour ne pas bloquer l'utilisateur dans sa navigation pendant que ses exports s'exécutent (il peut être bloqué un certain temps, cela ne pose pas de pb, mais au bout d'un moment je souhaiterais lui rendre la main pour poursuivre la navigation et récupérer son export plus tard (par mail par ex). L'autre solution à laquelle je pense est de faire une file d'attente dans une table sql et de lancer des taches planifiées pour scruter cette table a fréquence déterminée.

    Peut être existe t'il d'autres solutions, et peut être que ma question est dans le mauvais forum de discussion... Merci d'avance pour votre aide.

  2. #2
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 235
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 235
    Points : 15 532
    Points
    15 532
    Par défaut
    pour faire des traitements en arrière plan, vous pouvez les lancer avec cron, regardez l'article suivant :
    http://matthieu.developpez.com/execution_periodique/

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Merci pour votre réponse. Dois-je en déduire qu'il n'y a pas d'autre solution que de passer par une file d'attente et tache planifiée ?

  4. #4
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    A priori l'idée c'est jouable.

    e pense à une gestion par ticket

    la page demande sa requête d'export et reçoit un n° de ticket en retour

    pendant de temps le serveur constitue la réponse dans un fichier temporaire

    au bout d'un délai X la page demande au serveur si sa réponse est finalisée, un simple setTimeout( fct_demande, Délai_x).

    cette fct_demande est en fait une requête qui affiche soit le résultat s'il est finalisé, soit un message pour annoncer que la réponse arrivera par mail)

    Dans les 2 cas ni le serveur ni le post cliet ne sont enchainés l'un a l'autre.

    mais si tu tiens absolument à figer le poste client c'est faisable via les promesse JavaScript, mais c'est un peu particulier..
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par psychadelic Voir le message
    la page demande sa requête d'export et reçoit un n° de ticket en retour

    pendant ce temps le serveur constitue la réponse dans un fichier temporaire
    Merci psychadelic. J'ai du mal à comprendre comment déconnecter le serveur et le client pendant l'exécution de l'export. Quand la page demande sa requête d'export elle doit bien attendre la fin de l'export avant de se voir rendre la main? Comment donner un n° de ticket et lancer l'export en arrière plan ? (je développe en php)
    Si cela est faisable, je vois bien l'intérêt du setTimeout en js pour limiter le temps d'attente de l'utilisateur.

  6. #6
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    non, sur un navigateur, [et pour simplifier] toute opération d'entrée sortie se passe de manière asynchrone.

    par exemple , sur une page web, au chargement d'une page, le navigateur peut rencontrer N images à télécharger. Pour chacune des images il lance un mini process en parallèle qui une fois complètement chargée prendront leur place sur la page, mais en attendant le process principal de chargement [par exemple] du texte et des balises présentes sur la page à continué son bonhomme de chemin.
    D'ailleurs, dans le cas des images, si leur encombrement n'est pas connu avant le téléchargement , on peut voir à l'écran les re-calculs de positionnement des différents éléments de la page pour laisser la place aux images dont le chargement arrivant à terme.

    quand on utilise une requête Ajax c'est le même principe, le navigateur lance un process en parallèle qui se charge d'attendre le retour du serveur, mais le reste de la page reste entièrement autonome, on peut cliquer sur les boutons, scroller la page, etc, rien n'est figé.

    Ce que je te propose de faire c'est d'avoir 2 requêtes Ajax (mais en fait un peu plus mais c'est les 2 charnières du raisonnement)
    la première formule la requête d'export au serveur et reçoit en retour un ticket, ou si tu préfère nu numéro d'ordre.
    c'est de toutes façons une requette Ajax, parce qu'il s'agit d'un appel sur le serveur.

    Coté serveur PHP, à la réception de cette demande :
    1 - il fabrique le Ticket avec son numéro
    2 - il lance un process PHP à son tour pour réaliser le contenu à produire dans un fichier texte , dans un fichier texte en local sur le serveur, avec un référencement par exemple le fichier prend le nom du ticket.
    3 - il renvoie ce numéro de ticket au poste client.

    pour lancer un process parallèle sur un serveur il en passer par une commande exec php, => https://www.developpez.net/forums/d1...e/#post7018260
    sinon il existe un alternative un peu moins propre.

    ce processus paralele utilse ce numéro de ticket pour
    1 mettre un flag identifié par ce n° de ticket pour indiquer qu'il s'occupe de fabriquer ce fichier texte avec la méthode des 2 dossiers => dossier 1 = traitement en cours, dossier 2 = traitements terminés.
    une fois qu'il a terminé le job il déplace le fichier traité dans le dossier 2.



    sur le post client, à la réception de ce ticket , il lance un processus différé [avec ta durée d'attente] qui en principe devra récupérer le fichier texte, s'il est achevé.

    cad qu'il envoie une requête Ajax sur le serveur en se servant du ticket.

    à la réception de ce ticket, le serveur regarde si le dossier 2 contient le fichier, et dans ce cas il le balance en réponse au poste client, sinon il lui répond que le truc n'est pas pret.

    Voila l'idée, il y a bien sur des trucs à pofiner, comme par exemple le renvoi des fichier achevés "en retard", mais ça cç se lance via une tache répétitive en suivant la méthode de mathieu ici. ce qui signifie que tu dois avoir dans une base un conservation des n° de ticket avec les emails leur corresspondant.


    Il faut mieux utiliser aussi un dossier 3 fait pour les fichiers traités en envoi soit en réponse directe soit par mail, histoire d'éviter tout conflit entre ces 2 processus
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Merci pour cette réponse détaillée. Je vais tenter de l'appliquer.

    Si je peux abuser une dernière fois de votre temps, j'évoquais, dans mon message initial avoir tenté de résoudre mon pb avec une requête AJAX + timeout qui appelle une fonction PHP avec chrono (si chrono < timeout alors retourne le fichier, sinon envoie un mail avec le fichier). Elle fonctionnait bien, mais si je reprennais bien la main après le timeout, les boutons de navigation ne changeaient la page qu'une fois le mail envoyé, contrairement à ce que vous indiquez :

    Citation Envoyé par psychadelic Voir le message
    quand on utilise une requête Ajax c'est le même principe, le navigateur lance un process en parallèle qui se charge d'attendre le retour du serveur, mais le reste de la page reste entièrement autonome, on peut cliquer sur les boutons, scroller la page, etc, rien n'est figé.
    Est ce normal? Dois je creuser cette solution avant de tenter la votre ?

  8. #8
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    Comme j’ignore tout de ta solution, la mienne n’est juste qu’un conseil d’expérience, mais c’est pas garanti sur facture.

    Et je vois pas comment sur un navigateur puisse se figer au point de ne pouvoir reprendre la main qu’une fois un chrono écoulé, ça me semble être codé de manière peut orthodoxe. Dans ma solution c’est quelque chose qui ne peut pas arriver, les temps de chaque process sont trop courts pour que l’utilisateur puisse avoir l’impression d’un interface figé.

    Mais figer un interface ça reste quelque chose de faisable en code, mais il n’y a pas de rapport possible directement avec du code Ajax.
    (sauf si ton code est utilisé sur un Internet explorer 5 sur du Windows 2000, mais je demande à voir)


    Comme je te l’ai écris, et dans la partie que tu à recopié, le code Ajac s’exécute dans un process secondaire et en parallèle, ce qui ne vient en aucun cas figer l’interface du navigateur qui est sur sont process principal.

    Sinon, l’idée d’inclure un setTimeout dans une requête Ajax n’est absolument pas une bonne idée.

    La fonction setTimeout de JavaScript peut réserver des surprises, et il faut aussi se préserver d’un utilisateur fou qui clique 10 fois sur un bouton ce qui fini par envoyer autant de requêtes identiques.

    l’action sur le bouton doit d’abord mettre un flag pour marquer le traitement et donc décider d’agir ou non dans le cas ou un traitement précédent était lancé.
    Ensuite calculer un temps de référence pour le délai sur la réponse
    puis lancer la requête Ajax de demande
    puis lancer le process de récupération via un setTimeout.
    Comme ça il n’y a pas de mélange entre l’Ajax et le setTimeOut

    Le process de récupération compare son temps d’éxec avec le temps de référence, et s’il est bien supérieur alors il lance le processus de test de récupération, sinon il se relance.

    Pour une raison que j’ignore la fonction setrTimeout à tendance à être plus courte que prévue. c’est rare et ça arrive surtout quand on lance n fois des setTimeout ( il doit y avoir une histoire de cache ou je ne sais quoi, et je sais ça peut paraître dingue).
    d'ailleurs pour ceux qui en douterai encore la méthode delay de jQuery fonctionne aussi sur un calcul de temps pour éventuellement relancer un setTimeout.
    on peut aussi imaginer d'utiliser un setInterval que l'on aborte une fois la bonne durée écoulée.
    Toujours est-il que la programmation défensive n’a jamais tué personne.
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

Discussions similaires

  1. [Wamp] Gérer des requêtes lourdes avec Wamp
    Par dev14 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 10
    Dernier message: 11/01/2016, 16h58
  2. [PHP 5.3] Gérer des requêtes PHP trop longues
    Par xnopre dans le forum Langage
    Réponses: 9
    Dernier message: 09/03/2012, 19h41
  3. gérer des requête
    Par badiince dans le forum Programmation et administration système
    Réponses: 0
    Dernier message: 15/04/2009, 21h58
  4. Fichier log des requêtes d'une bdd
    Par Sub0 dans le forum Administration
    Réponses: 4
    Dernier message: 22/03/2004, 14h12
  5. Une unité pour gérer des très grands nombres
    Par M.Dlb dans le forum Langage
    Réponses: 2
    Dernier message: 09/09/2003, 12h07

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