Communauté Informatique NDFR.net

Communauté Informatique NDFR.net (http://www.ndfr.net/forums/index.php)
-   Programmation Web (HTML, PHP, ASP, Java, XML, etc.) (http://www.ndfr.net/forums/forumdisplay.php?f=65)
-   -   Rendre une opération indépendante d'un script PHP (http://www.ndfr.net/forums/showthread.php?t=6603)

KnuX 03-09-2005 15:41

Rendre une opération indépendante d'un script PHP
 
Salut à tous,
Le sujet sans doute pas clair, mais je vais m'expliquer plus ici...

J'ai fait un client IRC en PHP. Ce client a certaines opérations à effectuer, notamment une requête vers une base de données créées avec SQLite (www.sqlite.org) et les drivers PDO+PDO_SQLITE disponibles sur www.php.net.

Comme le client se connecte à un serveur IRC, il doit répondre régulièrement à la requête "PING" envoyée par le serveur, par un "PONG". Souvent, le délai de réponse est de 3 minutes avant que le serveur considère la connection comme perdue.

Seulement voilà, il arrive que la requête puisse prendre plus de 3 minutes (pitié, ne pas décaler mon problème en rétorquant que la base n'est pas optimisée ou je ne sais quoi, ce n'est pas la clé du problème). Dans cette situation, le serveur coupe donc la connexion puisque la lecture/écriture sur la socket est "suspendue" le temps que PHP attende la réponse d'SQLite.

Je cherche donc à pouvoir dire à PHP d'aller exécuter la requête tout en le laissant continuer son travaille d'écoute et d'écriture sur la socket. En fait, j'imagine ça comme une fonction qui s'occuperait de la requête et qui en appellerait une autre une fois celle-ci terminée (ce qui est parfois appelé un "callback" donc).

Quelqu'un aurait-il une idée ? On m'a proposé d'utiliser le "fork", je ne m'y connais pas trop et je voudrais savoir s'il n'y a pas des solutions envisageables...

Merci d'avance ;)

fonji 04-09-2005 18:53

Si j'ai bien tout compris, tu cherches à faire de la programmation concurrente en php...
Ca m'étonnerai fortement que ce soit possible...

Désolé mais j'ai pas tant d'idée... L'ouverture temporaire d'une nouvelle fenêtre pour effectuer le pong ne répondrait pas au serveur car ça changerait le port du client et donc le serveur prendrait ceci comme venant d'ailleurs...

KnuX 04-09-2005 23:37

Toujours pas trouvé non plus :(

Rasqual 05-09-2005 00:01

Bonjour,
C'est une solution que je n'ai pas testé, donc je ne garantis pas son fonctionnement.
Quelqu'un a récemment commenté sur le manuel en ligne que register_shutdown_function() est la seule manière de faire de la programmation asynchrone (si on exclut PCNTL, qui est non portable, je suppose)
L'idée serait de lancer un autre processus en fond pour effectuer les opérations sur SQLite, en faisant attention à ne pas lancer de tâche concurrente sur la base.
Dès que son travail est terminé, le processus communique avec l'appelant, via une socket. Le gros du boulot ce serait de gérer les erreurs, ce qui risque d'être bordélique si on ne fait pas attention.

Si tu ne vises que *nix (ce qui serait dommage), tu peux essayer de forker, mais là je ne m'y connais pas trop non plus.

Voilà, j'espère que cela t'aidera un peu.

Fred 06-09-2005 12:25

Ce genre d'exemple touche à la limite du php : il te faudrait 3 processus, l'un qui assure la liaison avec le serveur IRC, le second qui assure la liaison avec la base SQL et le dernier qui fasse l'interface avec l'utilisateur. Pour du temps réel, le PHP c'est quand même pas génial, mieux vaut sans doute tenter quelque chose en java ... tu as quelles contraintes pour ton projet ?

KnuX 06-09-2005 13:20

Ce n'est pas un projet, et je n'ai pas de contraintes particulières.

Si je venais à devoir mettre en production cette application, ce serait sur une machine serveur qui ne dispose pas de la JVM ;)

Mais bon, tant pis, pour l'instant je vais me contenter des performances d'sqlite3 qui sont nettement supérieures à celles de sqlite2, mon bot ne met même plus de 40 secondes pour chercher quelque chose :)

Si un jour je trouve une solution, je vous le dirais, merci pour l'aide ;)

fonji 06-09-2005 13:54

Sauf erreur pour un applet le serveur n'a pas besoin de jvm, mais le client oui...
Par contre, pour un servlet (donc du j2ee en gros), là c'est l'inverse... Je me trompe ?

KnuX 06-09-2005 14:32

Ce n'est pas une applet ;)

Ca se lance en ligne de commande et il n'y a pas d'interaction avec l'utilisateur (sauf avec d'autres clients IRC sur un salon ;))

Fred 06-09-2005 20:33

Pourquoi tu veux absolument faire le client IRC sur le serveur ? Qu'est-ce qui prend tant de temps à ta base de donnée (tes requêtes ne sont peut-être pas optimisées, ou la liaison est trop lente, je sais pas) ? As-tu essayé avec MySQL qui est semble-t-il plus rapide et plus complet ? Ne peux-tu pas simplement tester la connexion IRC après la requête et, si besoin est, te reconnecter (un downtime de 3 minutes, pour l'utilisateur, c'est quand même long ...) ?

KnuX 06-09-2005 20:52

- Le bot doit être connecté au serveur IRC puisque c'est là qu'on lui demande certaines choses
- Le choix de sqlite était par curiosité et parce que je n'avais pas de serveur SQL sous la main
- La lenteur, c'était sqlite2 qui mettait énormément de temps à faire un select count sur la base (il était en fait énormément long à parcourir son fichier). Avec sqlite3, pas photo ;)

Si besoin est, je m'arrangerais pour qu'il se reconnecte s'il ne l'est pas quand il donne les résultats.

"(pitié, ne pas décaler mon problème en rétorquant que la base n'est pas optimisée ou je ne sais quoi, ce n'est pas la clé du problème)"
Je sais que le choix de PHP et de SQLite n'était pas le plus pertinent, c'était une façon pour moi de faire un client IRC en PHP5 en utilisant des classes et de voir ce qu'SQLite a dans le ventre, j'ai aucun impératif ! ;)

Fred 07-09-2005 11:17

Et comment tu fais pour garder ton script actif longtemps sous php ? Tu désactives la limite de temps et tu fais une grande boucle ? Qu'est-ce qu'il y a dans ta base ? Après tout, à part pour l'initialisation, toutes les données pourraient être en mémoire, avec un backup de temps en temps dans la base (tu lance un autre script), ça éviterait tout tes problèmes et ça rendrait ton script plus réactif.

KnuX 07-09-2005 13:16

Le script est lancé en ligne de commande par le "command-line interpreter". Ce qui le maintient en vie, c'est la boucle d'écoute de la socket du serveur et de reconnexion si celle-ci se coupe :)

Dans la base, il n'y a qu'une table et des enregistrements sur trois champs uniques (représentant une adresse complète d'une connexion d'un client sur IRC : nick!ident@host).

La quantité d'informations est désormais importante, la limite par défaut de 8Mo de php empêchait un SELECT * from matable sans limit ;)

Fred 07-09-2005 19:35

Tu peux lever la limite de 8Mo, et si tu chargeais tous les champs au démarrage de ton application, ça t'éviterait de rappeler la base par la suite, et ce serait bien plus rapide ;)
Tu ne maintiens pas en mémoire uniquement les identifiants des personnes connectées ?

KnuX 07-09-2005 20:28

La base dépasse les 150Mo en fichier, il est hors de question que je réserve un tel espace en mémoire physique lol ;)

Et puis, c'était pas ce que je cherchais :p


All times are GMT +2. The time now is 06:17.

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.