Nettoyer les variables

Le
Denis Beauregard
Bonjour,

J'ai développé des logiciels qui fonctionnent par itération.

En gros, j'ai une entête comme la suivante :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
<meta http-equiv="refresh" content="1;url=suite.php">
</head>
<body>


et quand le 30 secondes est écoulé, l'itération suivante est
lancée. J'ai découvert plus tard qu'on pouvait prolonger ce
30 secondes mais j'avais déjà développé presque tout mon code



Mon code comprend une boucle et à chaque tour, on examine une
ligne dans une grosse base de données (200 000 ou 700 000 lignes
selon la base). Cet examen comprend toujours la lecture d'une
nouvelle ligne de données, mais aussi l'examen d'autres lignes
ainsi que l'écriture dans d'autres bases de données. Donc,

- un $query = 'SELECT MAX(id) FROM base'; pour trouver la dernière
ligne traitée quand le 30 secondes a été atteint

- au moins un 'SELECT * FROM base1 WHERE id = '.$eux;
- plusieurs SELECT et INSERT

et ceci pour quelques millieurs d'itérations à chaque fois

Il s'en suit un certain recyclage des variables mais j'ai
l'impression que ce recyclage est très imparfait et que la
mémoire disponible diminue à chaque boucle. Toutefois, aucun
moyen d'afficher le heap et le stack. J'ai fait des essais
avec memory_get_peak_usage et memory_get_usage et j'ai toujours
plus de 700 000 à ma disposition.

J'ai par ailleurs noté que si on fait un unset d'un array,
le contenu n'est pas vidé. J'ai fait un utilitaire pour le
faire :

function ViderArr ($arr) {
if (isset ($arr)) {
if (isset ($arr[$key])) unset($arr[$key]);
}
}
}


Ceci dit, j'ai l'impression d'avoir un débordement de mémoire que
je n'arrive pas à trouver. Le genre de bug intermittent qu'on
déteste avoir parce qu'il est trop difficile à détecter.

Y a-t-il moyen de vérifier rapidement si une variable déborde
autrement qu'en vérifiant pour chacune ?

Y a-t-il un moyen d'afficher le heap et le stack pour s'assurer
qu'il n'y a pas de collision ?

Y a-t-il un problème connu d'incompatibilité entre PHP et LibreOffice
ou d'autres logiciels ?

Y a-t-il une façon de vider toutes les variables ou presque à
chaque itération, autrement qu'avec des unset pour chacune ?

Mon principal symptôme : l'ordinateur arrête parfois pendant que mon
script PHP est exécuté (j'ai maintenant 4 scripts qui donnent ce
résultat).

Ma config :

Windows 7
Testé avec EasyPHP, puis Wampserver 2.5 et 3.06, donc des Apache,
PHP et mySQL différents
4 Go de mémoire

J'ai aussi varié quelques paramètres de php.ini
Je viens de faire un test intensif de mémoire (avec l'utilitaire
de Windows 7) et aucune erreur de ce côté.
PHP ne détecte aucune erreur. Le log montre seulement la fin des
blocs de 30 secondes et rien de plus.


Toute idée de solution sera appréciée.


Denis
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Olivier Miakinen
Le #26423924
Bonjour,
Le 10/01/2017 18:14, Denis Beauregard a écrit :
J'ai développé des logiciels qui fonctionnent par itération.

Ok.
En gros, j'ai une entête comme la suivante :
<html><head>
</head>
<body>
et quand le 30 secondes est écoulé, l'itération suivante est
lancée.

J'ai déjà une question : comment ton programme suite.php sait-il
où en était l'itération précédente ? En particulier, si plusieurs
utilisateurs accèdent au site en même temps, comment sait-il
s'il traite la suite de la requête faite par l'utilisateur 1 ou
par l'utilisateur 2 ?
J'ai découvert plus tard qu'on pouvait prolonger ce
30 secondes mais j'avais déjà développé presque tout mon code...

Qu'est-ce que ça change ? Pendant les 30 secondes séparant deux
appels HTTP, il n'y a pas de programme PHP qui tourne. Ce qui
pourrait avoir une influence, ce serait un programme JavaScript
lancé par la page affichée, mais tu n'en parles pas.
Mon code comprend une boucle et à chaque tour, on examine une
ligne dans une grosse base de données (200 000 ou 700 000 lignes
selon la base). Cet examen comprend toujours la lecture d'une
nouvelle ligne de données, mais aussi l'examen d'autres lignes
ainsi que l'écriture dans d'autres bases de données.

Je ne comprends pas ce que tu appelles « un tour ». C'est un tour
de boucle en PHP (donc il peut y en avoir 700 000 par appel HTTP)
ou bien c'est une itération (« HTTP refresh » -- et donc il y en a
un seul par appel du programme PHP) ?
Donc,
- un $query = 'SELECT MAX(id) FROM base'; pour trouver la dernière
ligne traitée quand le 30 secondes a été atteint

Tu veux dire une fois par appel, donc ?
- au moins un 'SELECT * FROM base1 WHERE id = '.$eux;
- plusieurs SELECT et INSERT
et ceci pour quelques millieurs d'itérations à chaque fois
Il s'en suit un certain recyclage des variables mais j'ai
l'impression que ce recyclage est très imparfait et que la
mémoire disponible diminue à chaque boucle. Toutefois, aucun
moyen d'afficher le heap et le stack. J'ai fait des essais
avec memory_get_peak_usage et memory_get_usage et j'ai toujours
plus de 700 000 à ma disposition.

Tu veux dire que chacun des scripts appelés semble disposer du
même espace mémoire, mais que la mémoire globale utilisée sur
l'ordinateur diminue ? Il faudrait voir s'il n'y a pas trop de
requêtes lancées simultanément suite aux refreshs... même si,
en principe, chaque nouvelle requête ne devrait démarrer que
30 secondes après la fin de la requête précédente.
J'ai par ailleurs noté que si on fait un unset d'un array,
le contenu n'est pas vidé. J'ai fait un utilitaire pour le
faire :
function ViderArr ($arr) {
if (isset ($arr)) {
if (isset ($arr[$key])) unset($arr[$key]);
}
}
}

C'est curieux, ce que tu dis. Comment constates-tu cela ?
Ceci dit, j'ai l'impression d'avoir un débordement de mémoire que
je n'arrive pas à trouver. Le genre de bug intermittent qu'on
déteste avoir parce qu'il est trop difficile à détecter.

Oui.
Y a-t-il moyen de vérifier rapidement si une variable déborde
autrement qu'en vérifiant pour chacune ?
Y a-t-il un moyen d'afficher le heap et le stack pour s'assurer
qu'il n'y a pas de collision ?

Je ne sais pas répondre à ces questions. Je ne suis d'ailleurs
pas sûr de les comprendre.
Y a-t-il un problème connu d'incompatibilité entre PHP et LibreOffice
ou d'autres logiciels ?

Alors là, je ne vois pas comment ce serait possible. Les logiciels
en question, ils tourneraient sur ton serveur web, ou bien sur la
machine cliente ?
Y a-t-il une façon de vider toutes les variables ou presque à
chaque itération, autrement qu'avec des unset pour chacune ?

Même question que supra pour les « tours » : de quelle itération
parles-tu ? S'il s'agit de requêtes HTTP différentes, les variables
doivent repartir à chaque fois dans l'état « non initialisé »,
il n'y a donc rien à vider. Ou alors c'est un vrai bug du moteur
PHP.
Mon principal symptôme : l'ordinateur arrête parfois pendant que mon
script PHP est exécuté (j'ai maintenant 4 scripts qui donnent ce
résultat).

Est-ce que tu peux avoir des statistiques sur le nombre de requêtes
HTTP par minute, et sur la durée moyenne de traitement d'une requête ?
Si tu as régulièrement une requête lancée toutes les 30 secondes
mais que chacune d'entre elles dure 40 secondes, alors il est normal
qu'au bout d'un moment ça sature.
Ma config :
Windows 7
Testé avec EasyPHP, puis Wampserver 2.5 et 3.06, donc des Apache,
PHP et mySQL différents
4 Go de mémoire
J'ai aussi varié quelques paramètres de php.ini
Je viens de faire un test intensif de mémoire (avec l'utilitaire
de Windows 7) et aucune erreur de ce côté.
PHP ne détecte aucune erreur. Le log montre seulement la fin des
blocs de 30 secondes et rien de plus.

Les 30 secondes, elles sont comptées sur la machine cliente, pas sur
le serveur. Alors quels sont ces « blocs de 30 secondes » dont le
log montrerait une fin ? Tu veux dire juste la réception d'une
nouvelle requête ?
--
Olivier Miakinen
Denis Beauregard
Le #26423926
Le Tue, 17 Jan 2017 17:35:58 +0100, Olivier Miakinen
Bonjour,
Le 10/01/2017 18:14, Denis Beauregard a écrit :
J'ai développé des logiciels qui fonctionnent par itération.

Ok.
En gros, j'ai une entête comme la suivante :
<html><head>
</head>
<body>
et quand le 30 secondes est écoulé, l'itération suivante est
lancée.

J'ai déjà une question : comment ton programme suite.php sait-il
où en était l'itération précédente ? En particulier, si plusieurs
utilisateurs accèdent au site en même temps, comment sait-il
s'il traite la suite de la requête faite par l'utilisateur 1 ou
par l'utilisateur 2 ?

L'utilisation est privée. Je compile des données chez moi et
je suis le seul à utiliser ces applications en local.
J'ai découvert plus tard qu'on pouvait prolonger ce
30 secondes mais j'avais déjà développé presque tout mon code...

Qu'est-ce que ça change ? Pendant les 30 secondes séparant deux
appels HTTP, il n'y a pas de programme PHP qui tourne. Ce qui
pourrait avoir une influence, ce serait un programme JavaScript
lancé par la page affichée, mais tu n'en parles pas.

Pas d'autre programme en parallèle. Par contre, l'ordinateur en
soi est utilisé pour autre chose. Ainsi, il y a un navigateur
(Seamonkey et Chrome en fait), et souvent Libreoffice.
Mon code comprend une boucle et à chaque tour, on examine une
ligne dans une grosse base de données (200 000 ou 700 000 lignes
selon la base). Cet examen comprend toujours la lecture d'une
nouvelle ligne de données, mais aussi l'examen d'autres lignes
ainsi que l'écriture dans d'autres bases de données.

Je ne comprends pas ce que tu appelles « un tour ». C'est un tour
de boucle en PHP (donc il peut y en avoir 700 000 par appel HTTP)
ou bien c'est une itération (« HTTP refresh » -- et donc il y en a
un seul par appel du programme PHP) ?

Une boucle pour chaque ligne, donc 700 000 boucles et chacune
comprend plusieurs appels à la base de données (query pour des
tables différentes).
Donc,
- un $query = 'SELECT MAX(id) FROM base'; pour trouver la dernière
ligne traitée quand le 30 secondes a été atteint

Tu veux dire une fois par appel, donc ?

oui
- au moins un 'SELECT * FROM base1 WHERE id = '.$eux;
- plusieurs SELECT et INSERT
et ceci pour quelques millieurs d'itérations à chaque fois
Il s'en suit un certain recyclage des variables mais j'ai
l'impression que ce recyclage est très imparfait et que la
mémoire disponible diminue à chaque boucle. Toutefois, aucun
moyen d'afficher le heap et le stack. J'ai fait des essais
avec memory_get_peak_usage et memory_get_usage et j'ai toujours
plus de 700 000 à ma disposition.

Tu veux dire que chacun des scripts appelés semble disposer du
même espace mémoire, mais que la mémoire globale utilisée sur
l'ordinateur diminue ? Il faudrait voir s'il n'y a pas trop de
requêtes lancées simultanément suite aux refreshs... même si,
en principe, chaque nouvelle requête ne devrait démarrer que
30 secondes après la fin de la requête précédente.

Un seul script à la fois (ou deux car je peux lancer 2 scripts
différents).
J'ai par ailleurs noté que si on fait un unset d'un array,
le contenu n'est pas vidé. J'ai fait un utilitaire pour le
faire :
function ViderArr ($arr) {
if (isset ($arr)) {
if (isset ($arr[$key])) unset($arr[$key]);
}
}
}

C'est curieux, ce que tu dis. Comment constates-tu cela ?

En regardant l'espace disponible selon que j'utilise ou pas
cette fonction.
Ceci dit, j'ai l'impression d'avoir un débordement de mémoire que
je n'arrive pas à trouver. Le genre de bug intermittent qu'on
déteste avoir parce qu'il est trop difficile à détecter.

Oui.
Y a-t-il moyen de vérifier rapidement si une variable déborde
autrement qu'en vérifiant pour chacune ?
Y a-t-il un moyen d'afficher le heap et le stack pour s'assurer
qu'il n'y a pas de collision ?

Je ne sais pas répondre à ces questions. Je ne suis d'ailleurs
pas sûr de les comprendre.
Y a-t-il un problème connu d'incompatibilité entre PHP et LibreOffice
ou d'autres logiciels ?

Alors là, je ne vois pas comment ce serait possible. Les logiciels
en question, ils tourneraient sur ton serveur web, ou bien sur la
machine cliente ?

Sur ma machine.
Y a-t-il une façon de vider toutes les variables ou presque à
chaque itération, autrement qu'avec des unset pour chacune ?

Même question que supra pour les « tours » : de quelle itération
parles-tu ? S'il s'agit de requêtes HTTP différentes, les variables
doivent repartir à chaque fois dans l'état « non initialisé »,
il n'y a donc rien à vider. Ou alors c'est un vrai bug du moteur
PHP.

Durant les 30 secondes d'un cycle, je peux boucler 5000 fois. Je
voudais vider toutes les variables 5000 fois (ou quand j'avance
d'une ligne dans le traitement de ma base de données).
Mon principal symptôme : l'ordinateur arrête parfois pendant que mon
script PHP est exécuté (j'ai maintenant 4 scripts qui donnent ce
résultat).

Est-ce que tu peux avoir des statistiques sur le nombre de requêtes
HTTP par minute, et sur la durée moyenne de traitement d'une requête ?
Si tu as régulièrement une requête lancée toutes les 30 secondes
mais que chacune d'entre elles dure 40 secondes, alors il est normal
qu'au bout d'un moment ça sature.

Je peux faire 15000 boucles dans une minutes et chaque boucle peut
disons faire 5 query en SQL. Donc je peux faire 75 000 appels à SQL
(le plus souvent des SELECT, parfois des INSERT) durant une minute.
Ma config :
Windows 7
Testé avec EasyPHP, puis Wampserver 2.5 et 3.06, donc des Apache,
PHP et mySQL différents
4 Go de mémoire
J'ai aussi varié quelques paramètres de php.ini
Je viens de faire un test intensif de mémoire (avec l'utilitaire
de Windows 7) et aucune erreur de ce côté.
PHP ne détecte aucune erreur. Le log montre seulement la fin des
blocs de 30 secondes et rien de plus.

Les 30 secondes, elles sont comptées sur la machine cliente, pas sur
le serveur. Alors quels sont ces « blocs de 30 secondes » dont le
log montrerait une fin ? Tu veux dire juste la réception d'une
nouvelle requête ?

Il y a une seule machine. C'est sur mon ordinateur personnel que tout
cela fonctionne, pas via Internet.
Denis
Olivier Miakinen
Le #26423930
Le 17/01/2017 18:12, Denis Beauregard m'a répondu :
J'ai déjà une question : comment ton programme suite.php sait-il
où en était l'itération précédente ? En particulier, si plusieurs
utilisateurs accèdent au site en même temps, comment sait-il
s'il traite la suite de la requête faite par l'utilisateur 1 ou
par l'utilisateur 2 ?

L'utilisation est privée. Je compile des données chez moi et
je suis le seul à utiliser ces applications en local.

Ok, donc la machine cliente est identique à la machine serveur, ce
qui ne facilite pas la distinction entre les deux. Mais tu passes
quand même par un navigateur web qui fait des requêtes au serveur
web, probablement sur localhost ?
J'ai découvert plus tard qu'on pouvait prolonger ce
30 secondes mais j'avais déjà développé presque tout mon code...

Qu'est-ce que ça change ? Pendant les 30 secondes séparant deux
appels HTTP, il n'y a pas de programme PHP qui tourne. Ce qui
pourrait avoir une influence, ce serait un programme JavaScript
lancé par la page affichée, mais tu n'en parles pas.

Pas d'autre programme en parallèle. Par contre, l'ordinateur en
soi est utilisé pour autre chose. Ainsi, il y a un navigateur
(Seamonkey et Chrome en fait), et souvent Libreoffice.

La page web rendue par ton script ne comporte donc aucun code
JavaScript.
Mon code comprend une boucle et à chaque tour, on examine une
ligne dans une grosse base de données (200 000 ou 700 000 lignes
selon la base). Cet examen comprend toujours la lecture d'une
nouvelle ligne de données, mais aussi l'examen d'autres lignes
ainsi que l'écriture dans d'autres bases de données.

Je ne comprends pas ce que tu appelles « un tour ». C'est un tour
de boucle en PHP (donc il peut y en avoir 700 000 par appel HTTP)
ou bien c'est une itération (« HTTP refresh » -- et donc il y en a
un seul par appel du programme PHP) ?

Une boucle pour chaque ligne, donc 700 000 boucles et chacune
comprend plusieurs appels à la base de données (query pour des
tables différentes).

On ne se comprend pas. Je te demande en gros combien il y a de
requêtes SQL pour une requête HTTP.
Sauf erreur de ma part, le scénario est le suivant (art ASCII
à voir avec une police à chasse fixe) :
========================================================== Navigateur Web Serveur Web
-------------- -----------
Requête HTTP
---------------->
Script PHP
avec requêtes SQL
<----------------
Réponse HTTP
(attente 30 secondes)
Requête HTTP
---------------->
Script PHP
avec requêtes SQL
<----------------
Réponse HTTP
(attente 30 secondes)
Requête HTTP
---------------->
Script PHP
avec requêtes SQL
<----------------
Réponse HTTP
(etc.)
==========================================================
Je me trompe ?
[...]
Même question que supra pour les « tours » : de quelle itération
parles-tu ? S'il s'agit de requêtes HTTP différentes, les variables
doivent repartir à chaque fois dans l'état « non initialisé »,
il n'y a donc rien à vider. Ou alors c'est un vrai bug du moteur
PHP.

Durant les 30 secondes d'un cycle, je peux boucler 5000 fois.

Je ne comprends pas ça. Pour moi, les 30 secondes démarrent lorsque
le serveur Web a rendu une réponse à la requête HTTP, réponse qui
comporte un entête « http-equiv ». Pendant ces 30 secondes, tu ne
peux pas boucler une seule fois puisque le programme PHP n'existe
pas.
[...]
Est-ce que tu peux avoir des statistiques sur le nombre de requêtes
HTTP par minute, et sur la durée moyenne de traitement d'une requête ?
Si tu as régulièrement une requête lancée toutes les 30 secondes
mais que chacune d'entre elles dure 40 secondes, alors il est normal
qu'au bout d'un moment ça sature.

Je peux faire 15000 boucles dans une minutes et chaque boucle peut
disons faire 5 query en SQL. Donc je peux faire 75 000 appels à SQL
(le plus souvent des SELECT, parfois des INSERT) durant une minute.

Je ne posais pas la question des requêtes SQL mais des requêtes HTTP.
Seulement il faut déjà éclaircir le «
Durant les 30 secondes d'un cycle, je peux boucler 5000 fois.
» car ça me semble tout bonnement impossible.
--
Olivier Miakinen
Denis Beauregard
Le #26423936
Le Tue, 17 Jan 2017 18:54:01 +0100, Olivier Miakinen
Le 17/01/2017 18:12, Denis Beauregard m'a répondu :
J'ai déjà une question : comment ton programme suite.php sait-il
où en était l'itération précédente ? En particulier, si plusieurs

L'utilisation est privée. Je compile des données chez moi et
je suis le seul à utiliser ces applications en local.

Ok, donc la machine cliente est identique à la machine serveur, ce
qui ne facilite pas la distinction entre les deux. Mais tu passes
quand même par un navigateur web qui fait des requêtes au serveur
web, probablement sur localhost ?

En fait, quand je suis passé à wampserver 3, localhost ou 127.0.0.1
est devenu un nom virtuel et je lance donc mes applications depuis
http://gfan/index.php
La page web rendue par ton script ne comporte donc aucun code
JavaScript.

Exact. PHP et SQL seulement.
Une boucle pour chaque ligne, donc 700 000 boucles et chacune
comprend plusieurs appels à la base de données (query pour des
tables différentes).

On ne se comprend pas. Je te demande en gros combien il y a de
requêtes SQL pour une requête HTTP.

Une requête HTTP par 30 secondes, et environ 35 000 requêtes
SQL à chaque fois.
Sauf erreur de ma part, le scénario est le suivant (art ASCII
à voir avec une police à chasse fixe) :
========================================================== > Navigateur Web Serveur Web
-------------- -----------
Requête HTTP
---------------->
Script PHP
avec requêtes SQL
<----------------
Réponse HTTP
(attente 30 secondes)
(etc.)

Plutôt :
Navigateur Web Serveur Web
-------------- -----------
Requête HTTP
---------------->
Script PHP
avec requêtes SQL
durant 30 secondes
avec réponses HTTP (les erreurs)
<----------------
Relance HTTP
En bref, mon écran affiche :
des données sur le traitement (numéro de départ, paramètres de
départ, étape), puis mon fichier d'erreurs, puis quand il y a une
erreur dans mes données (par exemple, le champ français est
renseigné mais pas le champ anglais), il y a un message. Il y a
aussi le numéro de la ligne courante (une fois par 1000 lignes).
Puis, PHP affiche Fatal error, time out, etc. et relance HTTP.
========================================================== >
Je me trompe ?

Voir plus haut.
[...]
Même question que supra pour les « tours » : de quelle itération
parles-tu ? S'il s'agit de requêtes HTTP différentes, les variables
doivent repartir à chaque fois dans l'état « non initialisé »,
il n'y a donc rien à vider. Ou alors c'est un vrai bug du moteur
PHP.

Durant les 30 secondes d'un cycle, je peux boucler 5000 fois.

Je ne comprends pas ça. Pour moi, les 30 secondes démarrent lorsque
le serveur Web a rendu une réponse à la requête HTTP, réponse qui
comporte un entête « http-equiv ». Pendant ces 30 secondes, tu ne
peux pas boucler une seule fois puisque le programme PHP n'existe
pas.

Pas tout à fait. L'en-tête est:
<meta http-equiv="refresh" content="1;url=suite.php"
Pas de durée. C'est réellement le script qui plante après 30 secondes
et donc la relance suit.
[...]
Est-ce que tu peux avoir des statistiques sur le nombre de requêtes
HTTP par minute, et sur la durée moyenne de traitement d'une requête ?
Si tu as régulièrement une requête lancée toutes les 30 secondes
mais que chacune d'entre elles dure 40 secondes, alors il est normal
qu'au bout d'un moment ça sature.

Je peux faire 15000 boucles dans une minutes et chaque boucle peut
disons faire 5 query en SQL. Donc je peux faire 75 000 appels à SQL
(le plus souvent des SELECT, parfois des INSERT) durant une minute.

Je ne posais pas la question des requêtes SQL mais des requêtes HTTP.
Seulement il faut déjà éclaircir le «
Durant les 30 secondes d'un cycle, je peux boucler 5000 fois.
» car ça me semble tout bonnement impossible.

Dit autrement :
entre deux requêtes HTTP (30 secondes), je peux boucler 5000 fois,
soit avancer de 5000 lignes dans la table à traiter. Pour chaque
ligne, je peux vérifier d'autres informations et donc avoir d'autres
énoncés SQL. En gros :
SELECT pour avoir la ligne à traiter (par exemple, un couple de
personnes mariées)
pour ce couple, je peux par exemple vérifier si le code de région
est valide (donc, un gros switch en PHP), si le code de la source
est valide (donc, une requête SQL parmi les 400 sources possibles),
etc. Une fois la ligne validée, je la retranscris dans une autre
table avec un INSERT.
Je répète disons 5000 fois, puis il y a le 30 secondes. Je vais
alors regarder jusqu'où j'ai écrit dans la nouvelle table, je
recule de 1 par précaution, et je recommence.
Le nombre de fois peut varier. 1000, 4526, 7801, etc.
Ce que je voudrais, c'est vider toutes les variables, puis utiliser
le SELECT comme pointeur pour la ligne suivante. Le hic, c'est que
ce serait beaucoup plus lent.
Denis
P.S. Je sais que c'est exactement comme cela qu'on programmait dans
les années 1970 avec un ordinateur central.
Olivier Miakinen
Le #26424141
Le 17/01/2017 20:13, Denis Beauregard a écrit :
Ok, donc la machine cliente est identique à la machine serveur, ce
qui ne facilite pas la distinction entre les deux. Mais tu passes
quand même par un navigateur web qui fait des requêtes au serveur
web, probablement sur localhost ?

En fait, quand je suis passé à wampserver 3, localhost ou 127.0.0.1
est devenu un nom virtuel et je lance donc mes applications depuis
http://gfan/index.php

Ok, ça revient au même, mais en effet c'est bien de le savoir.
[...]
Plutôt :
Navigateur Web Serveur Web
-------------- -----------
Requête HTTP
---------------->
Script PHP
avec requêtes SQL
durant 30 secondes
avec réponses HTTP (les erreurs)
<----------------
Relance HTTP
En bref, mon écran affiche :
des données sur le traitement (numéro de départ, paramètres de
départ, étape), puis mon fichier d'erreurs, puis quand il y a une
erreur dans mes données (par exemple, le champ français est
renseigné mais pas le champ anglais), il y a un message. Il y a
aussi le numéro de la ligne courante (une fois par 1000 lignes).
Puis, PHP affiche Fatal error, time out, etc. et relance HTTP.

Ok, c'est clair. Ce que je n'avais pas vu, c'est que le refresh
est fait au bout d'une seconde et pas de 30. À ma décharge,
c'est ta formulation dans ton premier article qui m'a induit
en erreur (tu montrais l'entête avec refresh puis tu enchaînais
sur « quand *le* 30 secondes est écoulé l'itération suivante
est lancée » (alors que c'est quand *la* seconde suivant le
retour du code PHP est écoulée).
[...]
Pas tout à fait. L'en-tête est:
<meta http-equiv="refresh" content="1;url=suite.php"
Pas de durée.

Si, mais c'est la durée la plus courte possible : une seconde.
C'est réellement le script qui plante après 30 secondes
et donc la relance suit.

Ok.
[...]
Dit autrement :
entre deux requêtes HTTP (30 secondes), je peux boucler 5000 fois,
soit avancer de 5000 lignes dans la table à traiter. Pour chaque
ligne, je peux vérifier d'autres informations et donc avoir d'autres
énoncés SQL. En gros :
SELECT pour avoir la ligne à traiter (par exemple, un couple de
personnes mariées)
pour ce couple, je peux par exemple vérifier si le code de région
est valide (donc, un gros switch en PHP), si le code de la source
est valide (donc, une requête SQL parmi les 400 sources possibles),
etc. Une fois la ligne validée, je la retranscris dans une autre
table avec un INSERT.

Est-ce que je comprends mieux cette fois : tu mets un timer de 30
secondes *en PHP*, et quand il est écoulé ça arrête les requêtes
SQL (après une moyenne de 5000 requêtes) et ça renvoie le résultat ?
Je répète disons 5000 fois, puis il y a le 30 secondes.

Gnîîî ? Quand tu dis « puis », cela veut dire qu'il y a d'abord
5000 requêtes, *puis* que tu attends 30 secondes ? C'est moi qui
suis bouché, ou toi qui n'expliques pas très bien ?
================================================================
Autre question. Je crois qu'il existe plusieurs modes de
lancement de PHP, dont le module Apache ou le mode CGI.
Si je ne m'abuse, dans le premier cas PHP est intégré à
Apache et n'est jamais arrêté (ce qui risque de le faire
grossir en cas de mauvaise gestion de la mémoire) alors
que dans le second cas le process est arrêté et relancé
à chaque fois (et là, si ça grossit, c'est un bug du
système d'exploitation).
Dans quel cas es-tu ?
================================================================
Dernier point : puisque tu es le seul utilisateur et que tout
se passe sur une seule machine, qui plus est sans JavaScript,
pourquoi passer par un navigateur web au lieu de lancer une
application PHP « standalone » ? Tu n'aurais pas besoin de
faire des arrêts toutes les 30 secondes pour satisfaire un
navigateur qui n'existe plus.
--
Olivier Miakinen
Denis Beauregard
Le #26424172
Le Fri, 20 Jan 2017 09:31:46 +0100, Olivier Miakinen
Le 17/01/2017 20:13, Denis Beauregard a écrit :
[...]
Dit autrement :
entre deux requêtes HTTP (30 secondes), je peux boucler 5000 fois,
soit avancer de 5000 lignes dans la table à traiter. Pour chaque
ligne, je peux vérifier d'autres informations et donc avoir d'autres
énoncés SQL. En gros :
SELECT pour avoir la ligne à traiter (par exemple, un couple de
personnes mariées)
pour ce couple, je peux par exemple vérifier si le code de région
est valide (donc, un gros switch en PHP), si le code de la source
est valide (donc, une requête SQL parmi les 400 sources possibles),
etc. Une fois la ligne validée, je la retranscris dans une autre
table avec un INSERT.

Est-ce que je comprends mieux cette fois : tu mets un timer de 30
secondes *en PHP*, et quand il est écoulé ça arrête les requêtes
SQL (après une moyenne de 5000 requêtes) et ça renvoie le résultat ?

C'est le timer par défaut. Il est effectivement géré par PHP.
Les résultats sont affichés immédiatement. J'ai les énoncés
ob_flush (); flush ();
tout de suite après un affichage afin de voir tout de suite une
erreur.
Je répète disons 5000 fois, puis il y a le 30 secondes.

Gnîîî ? Quand tu dis « puis », cela veut dire qu'il y a d'abord
5000 requêtes, *puis* que tu attends 30 secondes ? C'est moi qui
suis bouché, ou toi qui n'expliques pas très bien ?

La boucle tourne autour de 5000 fois, jusqu'à la fin du 30 secondes.
================================================================ >
Autre question. Je crois qu'il existe plusieurs modes de
lancement de PHP, dont le module Apache ou le mode CGI.
Si je ne m'abuse, dans le premier cas PHP est intégré à
Apache et n'est jamais arrêté (ce qui risque de le faire
grossir en cas de mauvaise gestion de la mémoire) alors
que dans le second cas le process est arrêté et relancé
à chaque fois (et là, si ça grossit, c'est un bug du
système d'exploitation).
Dans quel cas es-tu ?

Ce qui est installé par défaut dans Wampserver. Je suppose
que c'est le 2e cas puisqu'il y a 3 sections bien séparées
dans le code et donc que PHP n'est pas intégré à Apache.
================================================================ >
Dernier point : puisque tu es le seul utilisateur et que tout
se passe sur une seule machine, qui plus est sans JavaScript,
pourquoi passer par un navigateur web au lieu de lancer une
application PHP « standalone » ? Tu n'aurais pas besoin de
faire des arrêts toutes les 30 secondes pour satisfaire un
navigateur qui n'existe plus.

J'ai développé beaucoup de codes, de fonctions pour tel ou
tel rôle. Alors, c'est plus simple d'avoir tout le système
avec la même architecture, soit un écran principal. Je résume:
- 2 liens pour recompiler les données de couple, avec un
affichage du nombre des fichiers dont la version la plus
récente est un .xls (et non le .csv) parce sinon, je compile
la mauvaise version de mes données. Suivi d'une indication
de la dernière compilation
- 2 liens pour les données individuelels
- 1 lien pour vérification d'ensemble
- 1 lien pour préparer mes données avant de publier
- 1 lien pour publier mes données (créer un groupe de
pages web statiques)
- des liens pour refaire mes ststistiques, ajouter ADN, etc.
- des liens pour changer différents paramètres
- etc.
En bref, j'ai beaucoup de scripts et de fichiers. Plusieurs
ont un script de départ (remettre le compteur à zéro et vider
les tables). Cela donne une architecture un peu compliquée
mais aussi un tableau de bord qui me montre où j'en suis.
Par exemple, je peux modifier 5 fichiers, les retirer de
la mémoire, en modifier 5 autres, encore les retirer, puis
envoyer des données du fichier 1 vers le 2, en bref faire
beaucoup de modifications, sur plusieurs jours, avant de
recompiler.
Ceci dit, j'ai peut-être corrigé mon problème en nettoyant
physiquement l'intérieur de mon ordinateur. Il est possible
que le ventilateur du CPU avait trop de poussière et que le
CPU surchauffait facilement (et sans message d'erreur).
Cela fait 2 ou 3 fois que je recompile d'une façon telle que
l'ordi arrêtait systématiquement il y a quelques jours, mais
plus maintenant. J'aurais tout de même voulu savoir s'il y a
une façon de vider mes variables mais cela devient maintenant
académique.
Denis
Fredchou
Le #26424836
Le 20/01/2017 17:32, Denis Beauregard a écrit :
Gnîîî ? Quand tu dis « puis », cela veut dire qu'il y a d'abord
5000 requêtes, *puis* que tu attends 30 secondes ? C'est moi qui
suis bouché, ou toi qui n'expliques pas très bien ?

La boucle tourne autour de 5000 fois, jusqu'à la fin du 30 secondes.

J'avais utilisé le même genre d'astuce il y a pas mal de temps pour
faire des "traitements en masse" sur un serveur gratuit chez Free.
Est-ce que tu es sûr que ton script s'arrête de lui même "proprement"
AVANT la limite du serveur de 30 secondes ? Si ce n'est pas le cas, ton
script risque de s'arrêter dans un état "instable" qui peut expliquer
tes problèmes. Moi je prenais une marge de sécurité (par exemple : le
script s'arrête au bout de 20 secondes si la limite du serveur est à 30
secondes).
--
Fredchou
mailto:
Denis Beauregard
Le #26424902
Le Sun, 29 Jan 2017 18:34:23 +0100, Fredchou
Le 20/01/2017 17:32, Denis Beauregard a écrit :
Gnîîî ? Quand tu dis « puis », cela veut dire qu'il y a d'abord
5000 requêtes, *puis* que tu attends 30 secondes ? C'est moi qui
suis bouché, ou toi qui n'expliques pas très bien ?

La boucle tourne autour de 5000 fois, jusqu'à la fin du 30 secondes.

J'avais utilisé le même genre d'astuce il y a pas mal de temps pour
faire des "traitements en masse" sur un serveur gratuit chez Free.
Est-ce que tu es sûr que ton script s'arrête de lui même "proprement"
AVANT la limite du serveur de 30 secondes ? Si ce n'est pas le cas, ton
script risque de s'arrêter dans un état "instable" qui peut expliquer
tes problèmes. Moi je prenais une marge de sécurité (par exemple : le
script s'arrête au bout de 20 secondes si la limite du serveur est à 30
secondes).

Le script s'arrête "proprement". Pas de problème de ce côté. Il y a
toujours une position connue quand le script est interrompu et à la
reprise, je recule la position de 1. Sinon, il lit des données qui
sont tout simplement abandonnées, comme les variablse.
Denis
Publicité
Poster une réponse
Anonyme