Temporisation

Le
Pascale
Je dois effectuer un traitement sur une table qui contient environ 9000
enregistrements et génère autant de courriers électroniques (les
destinataires sont des associations inscrites au site, le message en
question contient une information importante). Simultanément, le contenu
d'un champ de la table est modifié pour chaque enregistrement.
Si je lance mon programme comme ça, mon hébergeur va couiner très très fort
et il aura raison parce que je vais lui saturer son serveur de courrier.
Est-ce qu'il y aurait un moyen simple de « ralentir » le programme, par une
sorte de temporisation de quelques secondes entre l'envoi de 2 messages ?

C'est une bête boucle, tout ce qu'il y a de classique :

$sel="SELECT valid,nom,theme,courriel,courrielv FROM matable";
$req = mysql_query($sel) or die('<CENTER>Erreur SQL
!'.'<br>'.mysql_error().'</CENTER>' );
while($data = mysql_fetch_array($req))
{
// traitement : modification + envoi d'e-mails
}

--
Pascale
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Olivier Miakinen
Le #16385051
Bonjour,

Le 21/07/2008 22:56, Pascale a écrit :

Est-ce qu'il y aurait un moyen simple de « ralentir » le programme, par une
sorte de temporisation de quelques secondes entre l'envoi de 2 messages ?



http://fr.php.net/sleep

Cordialement,
--
Olivier Miakinen
Pascale
Le #16386311
Olivier Miakinen news:4884f851$:

http://fr.php.net/sleep



Oui, j'ai trouvé ça entre le moment où j'ai posté et celui où le message
est paru (:
Mais ça va pas.

Si j'écris :

$sel="SELECT valid,nom,theme,courriel,courrielv FROM matable";
$req = mysql_query($sel) or die('<CENTER>Erreur SQL
!'.' while($data = mysql_fetch_array($req))
{
$valid=$data['valid'];
$nom=$data['nom'];
$theme=$data['theme'];
$courriel'=$data['courriel'];
echo 'Le courrier pour '.$nom.' sera envoyé à l'adresse
'.$courriel.<br />';
sleep(10);
}

et qu'il y a dans la table 11 enregistrements (c'est le cas dans ma table
de test), l'exécution du script semble prendre 11 x 10 secondes mais
s'effectuer quand même tout d'un bloc. Vrai z'ou faux ?... parce qu'avec
9000...

--
Pascale
Olivier Miakinen
Le #16386391
Le 22/07/2008 09:07, Pascale a écrit :

Si j'écris :

$sel="SELECT valid,nom,theme,courriel,courrielv FROM matable";
$req = mysql_query($sel) or die('<CENTER>Erreur SQL
!'.' while($data = mysql_fetch_array($req))
{
[...]
sleep(10);
}

et qu'il y a dans la table 11 enregistrements (c'est le cas dans ma table
de test), l'exécution du script semble prendre 11 x 10 secondes mais
s'effectuer quand même tout d'un bloc. Vrai z'ou faux ?... parce qu'avec
9000...



Je ne connais pas bien le fonctionnement des bases de données, mais je
suppose -- et tu sembles le confirmer -- que c'est le mysql_query() qui
fait tout le boulot en une seule fois sur l'ensemble de la table, alors
que mysql_fetch_array() ne fait que retourner, ligne par ligne, les
résultats déjà en mémoire.

Si tu veux limiter la requête elle-même, il est probable que tu doives
le faire dans « $sel » (je crois avoir vu quelque part une clause LIMIT)
et dans ce cas le bon forum pour en parler a toutes les chances d'être
fr.comp.applications.sgbd.
Antoine
Le #16387581
Pascale a écrit :
Si j'écris :

$sel="SELECT valid,nom,theme,courriel,courrielv FROM matable";
$req = mysql_query($sel) or die('<CENTER>Erreur SQL
!'.' while($data = mysql_fetch_array($req))
{
$valid=$data['valid'];
$nom=$data['nom'];
$theme=$data['theme'];
$courriel'=$data['courriel'];
echo 'Le courrier pour '.$nom.' sera envoyé à l'adresse
'.$courriel.<br />';
sleep(10);
}

et qu'il y a dans la table 11 enregistrements (c'est le cas dans ma table
de test), l'exécution du script semble prendre 11 x 10 secondes mais
s'effectuer quand même tout d'un bloc. Vrai z'ou faux ?... parce qu'avec
9000...




Bonjour,

Peux tu préciser ce qui te donne cette impression ? Peut-être celà
vient-il du fait que la page sur laquelle tu exécute le script n'affiche
rien pendant 11x10 sec, et qu'elle envoie tout à la fin. C'est u
fonctionnement normal, PHP (Hypertext PRE-Processor) interprète tout le
code d'une page avant d'en renvoyer le contenu à ton navigateur. Je
pense d'après ton code qu'il y a bien une pause effectuée entre chaque
tour de boucle.

D'après ton code, la requête de sélection des 9000 entrées ne devrait
pas surcharger MySQL (il sert à ça). En revanche si dans ta boucle
(comme tu l'a expliqué dans ton premier message) tu fais un UPDATE sur
un champ de ta table, là il y a une montée en charge. Normalement avec
un sleep de 10 secondes, pas de souci ;)

Cordialement

Antoine
Anthony
Le #16389441
Pascale a écrit :
Je dois effectuer un traitement sur une table qui contient environ 9000
enregistrements et génère autant de courriers électroniques (les
destinataires sont des associations inscrites au site, le message en
question contient une information importante). Simultanément, le contenu
d'un champ de la table est modifié pour chaque enregistrement.
Si je lance mon programme comme ça, mon hébergeur va couiner très très fort
et il aura raison parce que je vais lui saturer son serveur de courrier.
Est-ce qu'il y aurait un moyen simple de « ralentir » le programme, par une
sorte de temporisation de quelques secondes entre l'envoi de 2 messages ?

C'est une bête boucle, tout ce qu'il y a de classique :





je crains que vous ne puissiez utiliser ce type de ralentissement
(sleep)... parce que votre hébergeur a plus que certainement mis une
durée d'exécution relativement basse... et votre script en pâtira.

Je vous conseille la chose suivante (avec test en amont sans envoyer les
mails bien entendu) :

Vous arrivez sur le script pour la première fois ($start=0) et envoyez X
mails ( 500 par exemple) : LIMIT $start,500

Tant que la liste complète n'est pas envoyer... un petit :
meta name en html pour relire la page au bout de X seconde... cette fois
avec $start+500 )

Du coup votre script continu d'envoyer les mails et de se « réexecuter »
X fois jusqu'à ce que tous les mails soient partis.

Anthony
Bruno Desthuilliers
Le #16389451
Pascale a écrit :
Je dois effectuer un traitement sur une table qui contient environ 9000
enregistrements et génère autant de courriers électroniques (les
destinataires sont des associations inscrites au site, le message en
question contient une information importante). Simultanément, le contenu
d'un champ de la table est modifié pour chaque enregistrement.
Si je lance mon programme comme ça, mon hébergeur va couiner très très fort
et il aura raison parce que je vais lui saturer son serveur de courrier.



La plupart des serveurs de courriers sortant sont capables d'envoyer un
même mail à plusieurs destinataires en même temps (en utilisant
l'entête bcc (blind carbon copy). En bref : ce n'est pas parce que tu
dois poster un mail à 9000 destinataires que tu dois envoyer 9000 mails
(à moins bien sûr que le mail soit personnalisé pour chaque destinataire).

Ceci étant, les programmes de gestion de newsletter ne manquent pas.
A-tu une raison particulière de vouloir réinventer la roue ?
Pascale
Le #16389461
Olivier Miakinen news:48858920$:

Je ne connais pas bien le fonctionnement des bases de données, mais je
suppose -- et tu sembles le confirmer -- que c'est le mysql_query() qui
fait tout le boulot en une seule fois sur l'ensemble de la table, alors
que mysql_fetch_array() ne fait que retourner, ligne par ligne, les
résultats déjà en mémoire.



Oui, c'est ça.

Si tu veux limiter la requête elle-même, il est probable que tu doives
le faire dans « $sel » (je crois avoir vu quelque part une clause LIMIT)
et dans ce cas le bon forum pour en parler a toutes les chances d'être
fr.comp.applications.sgbd.



Oui, je pourrais le faire en passant par une table intermédiaire où
j'effacerais les enregistrements au fur et à mesure de la progression, mais
c'est plus compliqué (d'autant que je modifie un champ dans la table
d'origine).

--
Pascale
Pascale
Le #16389471
Antoine news:4885a167$0$16993$:

Bonjour,

Peux tu préciser ce qui te donne cette impression ? Peut-être celà
vient-il du fait que la page sur laquelle tu exécute le script
n'affiche rien pendant 11x10 sec, et qu'elle envoie tout à la fin.
C'est u fonctionnement normal, PHP (Hypertext PRE-Processor)
interprète tout le code d'une page avant d'en renvoyer le contenu à
ton navigateur. Je pense d'après ton code qu'il y a bien une pause
effectuée entre chaque tour de boucle.



Je viens de me rendre compte que tu as parfaitement raison ! Mon impression
était mauvaise ! Je viens de faire tourner le programme sur un échantillon de
11 envois. Que je fasse ou pas l'update, avec une sleep à 10 secondes, les
courriels arrivent espacés de 12 secondes.
Ce qui me fait en gros une trentaine d'heures d'envoi, mais ce n'est pas très
gênant : en principe, le programme peut être interrompu et repris n'importe quand ;
la requête d'update modifie un champ dont la valeur était obligatoirement comprise
entre 1 et 99 et passe à un chiffre compris entre 101 et 999, donc si ce champ a
une valeur supérieure à 100, l'enregistement a déjà été traité, il est ignoré.

D'après ton code, la requête de sélection des 9000 entrées ne devrait
pas surcharger MySQL (il sert à ça). En revanche si dans ta boucle
(comme tu l'a expliqué dans ton premier message) tu fais un UPDATE sur
un champ de ta table, là il y a une montée en charge. Normalement avec
un sleep de 10 secondes, pas de souci ;)



En fait, l'UPDATE lui-même ne pose pas de problème de surcharge du serveur,
même avec 9000 enregistrements, en quelques secondes c'est plié.
Ce qui pose problème, c'est uniquement l'envoi de courriels, presque 9000 d'un
coup, je sais que le serveur de mail de mon hébergeur va saturer si je lui fais
cette vilaine blague.
Reste à savoir si le fait de mettre une commande sleep de quelques secondes
entre 2 envois suffira à ne pas le contrarier... ou s'il vaut mieux tout bêtement
mettre un LIMIT 50 dans le SELECT de départ et relancer automatiquement le programme
toutes les 3 minutes, par exemple...

Merci beaucoup à Olivier et à toi.

--
Pascale
Paul
Le #16390301
Pascale a écrit :
.....
Reste à savoir si le fait de mettre une commande sleep de quelques secondes
entre 2 envois suffira à ne pas le contrarier... ou s'il vaut mieux tout bêtement
mettre un LIMIT 50 dans le SELECT de départ et relancer automatiquement le programme
toutes les 3 minutes, par exemple...



Si tu poses la question à ton FAI, tu auras sa réponse ! ;-)
Perso je pencherais plutôt vers la seconde solution. Ces deux phrases
pouvant être reliées par la réponse à la question : Combien de mails
simultanés maximum pour ne pas être considérée comme une spameuse ?
J'eqça.
PAUL
Pascale
Le #16390311
Bruno Desthuilliers news:4885cc73$0$2329$:

En bref : ce n'est pas parce que tu
dois poster un mail à 9000 destinataires que tu dois envoyer 9000
mails (à moins bien sûr que le mail soit personnalisé pour chaque
destinataire).



Il l'est, et particulièrement celui-ci.

Ceci étant, les programmes de gestion de newsletter ne manquent pas.
A-tu une raison particulière de vouloir réinventer la roue ?



Ben justement, c'est pas vraiment une newsletter...

--
Pascale
Publicité
Poster une réponse
Anonyme