Discussion:
script long
(trop ancien pour répondre)
Y a personne
2008-08-01 21:08:48 UTC
Permalink
Bonjour,

je dois envoyer une newsletter avec un max de 100 / minute.

je pense que dois utiliser la fonction sleep();

mais la question c'est comment faire pour que le script aille à son
terme en sachant qu'il y a des milliers d'adresses.

Le script risque de s'arrêter du à une durée trop longue ou
l'utilisateur risque de fermer la fenêtre en pensant que le programme
est bloqué.

merci de votre aide
Olivier Miakinen
2008-08-01 21:25:46 UTC
Permalink
Post by Y a personne
je dois envoyer une newsletter avec un max de 100 / minute.
Le plus simple : utiliser une vraie liste de diffusion au lieu de
bricoler en PHP. Les avantages sont la simplicité d'utilisation, le
fait que tu peux offrir la possibilité aux gens de s'inscrire et de
se désinscrire par eux-mêmes, la vérification automatiques que les
adresses ne sont pas en erreur, le moindre risque d'être pris pour
un spammeur, etc.
Post by Y a personne
je pense que dois utiliser la fonction sleep();
Tu arrives à la même conclusion que Pascale la semaine dernière, pour
ses requêtes à la base de données (sujet : Temporisation).
Post by Y a personne
mais la question c'est comment faire pour que le script aille à son
terme en sachant qu'il y a des milliers d'adresses.
Le script risque de s'arrêter du à une durée trop longue ou
Non. Cf. ma réponse à Pascale.
Post by Y a personne
l'utilisateur risque de fermer la fenêtre en pensant que le programme
est bloqué.
Euh... parce que c'est n'importe quel visiteur qui déclenchera l'envoi
des vagues de courriel, et qu'il est censé attendre la fin ??? Note
que tu peux aussi te contenter de déclencher le lancement d'un script
(PHP ou autre) à partir de ta page en PHP.
Post by Y a personne
merci de votre aide
Bof. Lis les autres fils traitant de ce sujet (cela arrive plusieurs
fois dans l'année) et, si tu ne trouves pas ton bonheur, reviens en
expliquant exactement de quoi il s'agit et pourquoi c'est un script PHP
lancé à distance (plutôt qu'en ligne de commande) qui doit s'en charger.
Denis Beauregard
2008-08-01 22:21:41 UTC
Permalink
Post by Olivier Miakinen
Post by Y a personne
je dois envoyer une newsletter avec un max de 100 / minute.
Le plus simple : utiliser une vraie liste de diffusion au lieu de
bricoler en PHP. Les avantages sont la simplicité d'utilisation, le
fait que tu peux offrir la possibilité aux gens de s'inscrire et de
se désinscrire par eux-mêmes, la vérification automatiques que les
adresses ne sont pas en erreur, le moindre risque d'être pris pour
un spammeur, etc.
Tu oublies les inconvénients.

Tout d'abord, est-on certain que tout le monde recevra le message ?
J'ai fait l'essai avec mon association et les abonnés aux bases de
données en ligne (tout le monde doit faire une demande par courriel,
donc cela nous a donné plus de 1000 courriels). Une petite partie
seulement des gens recevaient le message et j'ai utilisé une vraie
liste populaire, mailman, qui gère des listes beaucoup plus grosses
sur d'autres sites. Donc, si la liste est mal installée, il y a un
risque.

Ensuite, certains FAI bloquent tout ce qui vient d'une liste
identifiée.
Post by Olivier Miakinen
Post by Y a personne
je pense que dois utiliser la fonction sleep();
Tu arrives à la même conclusion que Pascale la semaine dernière, pour
ses requêtes à la base de données (sujet : Temporisation).
Post by Y a personne
mais la question c'est comment faire pour que le script aille à son
terme en sachant qu'il y a des milliers d'adresses.
Le script risque de s'arrêter du à une durée trop longue ou
Moi je noterais dans un fichier les envois, du moins le
numéro séquentiel, et s'il y a une interruption, je repartirais
du suivant.


Denis
Mickael Wolff
2008-08-02 17:13:29 UTC
Permalink
Post by Denis Beauregard
Tout d'abord, est-on certain que tout le monde recevra le message ?
J'ai fait l'essai avec mon association et les abonnés aux bases de
données en ligne (tout le monde doit faire une demande par courriel,
donc cela nous a donné plus de 1000 courriels).
Même en utilisant la fonctionnalité « Mass Subscribe Users » ?
Post by Denis Beauregard
Ensuite, certains FAI bloquent tout ce qui vient d'une liste
identifiée.
Ah ? Qui ? Pourquoi ?
Post by Denis Beauregard
Moi je noterais dans un fichier les envois, du moins le
numéro séquentiel, et s'il y a une interruption, je repartirais
du suivant.
Pas très fiable comme méthode. Il vaut mieux avoir une base de
données dans laquelle tu gères un champs indiquant la date de la
dernière ML envoyée, par exemple.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Denis Beauregard
2008-08-02 20:43:24 UTC
Permalink
Post by Mickael Wolff
Post by Denis Beauregard
Tout d'abord, est-on certain que tout le monde recevra le message ?
J'ai fait l'essai avec mon association et les abonnés aux bases de
données en ligne (tout le monde doit faire une demande par courriel,
donc cela nous a donné plus de 1000 courriels).
Même en utilisant la fonctionnalité « Mass Subscribe Users » ?
Euh, cela est pour abonner les gens... J'ai extrait de ma base de
données les courriels des personnes inscrites et j'ai ajouté cette
liste d'adresses à celle des abonnés de la liste de diffusion via
cette fonction (j'ai la version française toutefois). J'ai essayé
2 fois de faire des envois à tout le monde, à chaque fois avec plus
de 1000 abonnés, et les deux fois, une partie seulement des gens
avaient reçu les messages. Si quelqu'un a la solution, je suis
preneur ! Mais je n'ai pas accès au code interne de la liste ni
à sa base de données, donc je ne peux pas voir s'il y a une limite
au nombre d'abonnés sur le serveur.
Post by Mickael Wolff
Post by Denis Beauregard
Ensuite, certains FAI bloquent tout ce qui vient d'une liste
identifiée.
Ah ? Qui ? Pourquoi ?
En 2005, j'ai créé un système de bases de données et celui-ci
envoie un message avec le mot de passe et un lien pour cliquer.
Les abonnés d'AOL ne recevaient jamais le message, ainsi que
certains rares FAI et il fallait alors recopier le message
envoyé dans un courriel privé (je recevais une copie du message
envoyé). Donc, certains FAI vérifient au moins le contenu de
l'entête (ou autre chose ?) et refusent ce qui ne vient pas
d'un humain. Et de mémoire, il me semble que certains devaient
prendre une adresse différente pour s'abonner à certaines listes.
La raison serait qu'on considère que c'est du spam.
Post by Mickael Wolff
Post by Denis Beauregard
Moi je noterais dans un fichier les envois, du moins le
numéro séquentiel, et s'il y a une interruption, je repartirais
du suivant.
Pas très fiable comme méthode. Il vaut mieux avoir une base de
données dans laquelle tu gères un champs indiquant la date de la
dernière ML envoyée, par exemple.
Cela dépend toujours d'un grand nombre de facteurs. D'un côté,
c'est plus rapide et plus simple d'écrire dans un fichier un numéro
de séquence (si on suppose que les envois se font toujours en
suivant une séquence précise). On ouvre le fichier, on écrit et
on ferme. D'un autre côté, si on ajoute des fonctions comme le
départ en vacances et l'interruption des envois, avec reprise au
retour de vacances et l'envoi des numéros manquants, donc si on
veut plus de gadgets, une BDD permet de le faire plus facilement.

Ceci dit, je ne vois pas en quoi ma méthode est moins fiable. Le
message est envoyé à la main quand il est prêt et non de façon
automatisé (comme le sommaire ou la compilation des messages du
jour etc.) puisque c'est une "newsletter" (je préfère une revue ou
un bulletin, comme on peut lire dans les anciens imprimés sur un
site comme gallica.bnf.fr). Donc, le message est envoyé à tout le
monde en même temps, en suivant une séquence d'envoi. Le problème
était que la séquence pouvait être interrompue pour une raison
quelconque (time out en particulier).


Denis
Mickael Wolff
2008-08-03 20:42:36 UTC
Permalink
Post by Denis Beauregard
[...]
Merci pour la confirmation.
Post by Denis Beauregard
En 2005, j'ai créé un système de bases de données et celui-ci
envoie un message avec le mot de passe et un lien pour cliquer.
Les abonnés d'AOL ne recevaient jamais le message, ainsi que
certains rares FAI et il fallait alors recopier le message
envoyé dans un courriel privé (je recevais une copie du message
envoyé). Donc, certains FAI vérifient au moins le contenu de
l'entête (ou autre chose ?) et refusent ce qui ne vient pas
d'un humain.
Il n'y a que l'en-tête qui permette de véritablement savoir si le
courriel a été envoyé via un MUA automatique ou non.

Mais cette approche est naïve, puisqu'au final, maintenant, si tu
regardes les en-têtes de Spam, on s'apperçois qu'ils ajouteur un
X-User-Agent correspondant à un MUA interactif.

À noter que des imbéciles comme le « malfameux » Hotmail jettent
directement les courriels en text/plain.
Post by Denis Beauregard
Et de mémoire, il me semble que certains devaient
prendre une adresse différente pour s'abonner à certaines listes.
La raison serait qu'on considère que c'est du spam.
Pour ne pas être traité comme du Spam, il n'y a malheureusement pas
de solution miracle. Les faux-positifs sont malheureusement très nombreux.
Post by Denis Beauregard
Cela dépend toujours d'un grand nombre de facteurs. D'un côté,
c'est plus rapide et plus simple d'écrire dans un fichier un numéro
de séquence (si on suppose que les envois se font toujours en
suivant une séquence précise). On ouvre le fichier, on écrit et
on ferme. D'un autre côté, si on ajoute des fonctions comme le
départ en vacances et l'interruption des envois, avec reprise au
retour de vacances et l'envoi des numéros manquants, donc si on
veut plus de gadgets, une BDD permet de le faire plus facilement.
Je ne pense pas que la performance temporelle soit le premier
critère. Je préfère privilégier la fiabilité dans ces cas-là.
Post by Denis Beauregard
Ceci dit, je ne vois pas en quoi ma méthode est moins fiable.
L'écriture dans un fichier texte depuis un script PHP fortement
sollicité donne des résultats surprenants. Et ce malgré l'utilisation de
flock.
Post by Denis Beauregard
Donc, le message est envoyé à tout le
monde en même temps, en suivant une séquence d'envoi. Le problème
était que la séquence pouvait être interrompue pour une raison
quelconque (time out en particulier).
Le timeout du navigateur ne joue pas. Seul le timeout d'exécution du
script PHP le peu.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Mickael Wolff
2008-08-02 17:13:29 UTC
Permalink
Post by Y a personne
Le script risque de s'arrêter du à une durée trop longue ou
l'utilisateur risque de fermer la fenêtre en pensant que le programme
est bloqué.
Comment le serveur détecte que la fenêtre du navigateur a été fermée ?
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
TJ
2008-08-04 11:30:03 UTC
Permalink
Post by Mickael Wolff
Post by Y a personne
Le script risque de s'arrêter du à une durée trop longue ou
l'utilisateur risque de fermer la fenêtre en pensant que le programme
est bloqué.
Comment le serveur détecte que la fenêtre du navigateur a été fermée ?
En fait, plutôt que la fermeture de fenêtre, je pense que l'OP pensait
au cas où le client clôt le socket. Dans ce cas le comportement usuel de
PHP est d'interrompre l'exécution du script correspondant à la requête.

Cela dit, dans de nombreux navigateurs, je suppose que les actions
suivantes provoque une fermeture du socket utilisé :

* fermeture de l'onglet ou fenêtre contentant le résultat de la
requête
* bouton « stop » ou équivalent


Côté PHP on peut forcer l'exécution à être menée à son terme même si
la connexion est fermé avant la fin de l'exécution par le client :

http://php.net/ignore_user_abort
Y a personne
2008-08-04 16:12:09 UTC
Permalink
Post by Mickael Wolff
Post by Y a personne
Le script risque de s'arrêter du à une durée trop longue ou
l'utilisateur risque de fermer la fenêtre en pensant que le programme
est bloqué.
Comment le serveur détecte que la fenêtre du navigateur a été fermée ?
Merci pour votre aide


Je viens de faire quelques petits tests.


une boucle for 5x qui fait un insert dans une table avec un délai de 10
sec (sleep(10)).

Donc, le script doit durée ~50sec.

j'ai mis set_time_limit(0); pour que le script puisse durée plus de 30 sec.

dès que je démarre le script, je ferme l'onglet et dans l'autre onglet
je refresh la table qui s'incrémente de 1 ligne toutes les 10 sec. (un
champ timestamp comme preuve)

ca fonctionne correctement.

Est-ce donc comme cela que je dois procéder pour envoyer ma newsletter.

si j'envoie un script avec l'envoie de 50.000 mails avec 100 par minute.

Mon script risque de durée plus de 8 heures.

y'a t'il des risque à cela ? est-ce que le serveur vas exécuter le
script jusqu'au bout ?


merci
TJ
2008-08-04 20:40:20 UTC
Permalink
Post by Y a personne
y'a t'il des risque à cela ? est-ce que le serveur vas exécuter le
script jusqu'au bout ?
S'il n'est pas redémarré oui, je préfère préciser car j'ai déjà
rencontré un cas où l'admin faisait un « restart » du serveur pour
tourner les logs plutôt qu'un « graceful », ce qui avait pour effet de
terminer les requêtes en cours. Il s'agissait d'Apache.

Cependant, pour un script qui va durer 8 heures, ne serait-il pas
préférable de l'invoquer directement par PHP plutôt que par
l'intermédiaire d'un serveur Web ? Si le côté déclenchement par le web
est indispensable, cela peut être un simple script web qui positionne un
flag en base, couplé avec un script cron lancé toutes les heures qui
vérifie le flag en base et qu'il n'est pas lui-même (le script) déjà en
cours d'exécution. De plus dans ce cas vous recevrez la sortie du script
par mail une fois l'exécution terminée.
John GALLET
2008-08-05 13:42:39 UTC
Permalink
Post by Y a personne
si j'envoie un script avec l'envoie de 50.000 mails avec 100 par minute.
Une fois de plus(*): mauvais hébergeur, changer d'hebergeur. Si on a des
volumes aussi importants, on se prend les moyens de lancer ses scripts PHP
en crontab et avec un serveur de mail qui tient la route derrière.
Post by Y a personne
y'a t'il des risque à cela ? est-ce que le serveur vas exécuter le script
jusqu'au bout ?
Il y a peu de chances qu'il n'y ait pas au moins un truc qui merde en une
période de 8 heures. Par exemple, moi je redémarre mes process apache
toutes les nuits. Une application directe du Théorème de Murphy démontre
que le redémarrage aura lieu pendant l'exécution et arrêtera tout.

Remarque de parallélisation: il est parfois intéressant d'avoir plusieurs
tâches en parallèle sur des volumes de ce genre. Il est super facile de
trouver un critère de mutex au lieu de gérer des locks (par exemple, si
j'ai 3 tâches parallèles, je prends le modulo 3 d'un identifiant
numérique comme critère de sélection).

Remarque d'antispam: ne pas confondre FAI et antispam. Il faut envoyer le
courrier sur une adresse filtrée par SpamAssassin et voir pour avoir une
idée du score (et encore, chaque installation a ses propres
caractéristiques). Il est clair que certains MUA sont dans mes blacklists.

(*) cf le thread indiqué par Olivier, "temporisation".

a++;
JG

Continuer la lecture sur narkive:
Loading...