Lancement de tâches cron automatiques depuis PHP

Petit nouveau ! | 8 Messages

18 juil. 2012, 20:23

Lancement de tâches cron automatiques depuis PHP

Bonjour à tous,

Je poste un message sur ce forum car après maintes recherches sur le web, je ne trouve pas la solution à mon problème.
D'habitude je ne suis pas du genre à poster des messages à tout va, je trouve habituellement ce que je cherche.

Mais dans ce cas précis, je m'avoue vaincu. C'est d'autant plus bizarre parce que j'ai déjà vu ce genre de compteurs dans plein de jeux.
J'explique mon problème : je dois développer un jeu en ligne avec des timers de partout, c'est-à-dire que chaque joueur va voir se réinitialiser ses objets toutes les X heures (avec un compteur qui tourne devant ses yeux, qui remet à jour la page à la fin, et même s'il n'est pas connecté, le traitement se fait quand même).

Pour le compteur qui tourne, je l'ai implémenté en jquery, maintenant le gros souci c'est comment faire pour que chaque joueur ait ses propres tâches automatiques qui tournent toutes seules et qui vont aller mettre à jour la bdd? comment programmer les tâches cron pour chaque joueur, à la seconde près (sachant que les cron ne fonctionnent pas avec des secondes, et qu'elles sont parfois limitées en nombre de lignes, ou parfois il faut être en root pour les modifier...), en synchronisant le compteur jquery arrivé à 00:00:00 avec la tâche cron... #-o

Peut-être qu'il faut que je m'oriente vers un script de file d'attente qui tourne en permanence, je n'en sais rien. Si vous avez une idée, je vous en remercie d'avance!

ViPHP
xTG
ViPHP | 7331 Messages

18 juil. 2012, 21:22

Ce n'est pas la bonne idée, tu vas surcharger ton serveur de tâches Cron et tu vas le faire exploser. ;)
Le principe c'est d'avoir un timestamp de dernière actualisation.
Ensuite à la prochaine demande d'accès aux données concernées (par le joueur, ou par l'appel d'un tableau statistique ou que sais-je encore) faire la mise à jour.
Tu auras la différence entre le timestamp actuel et le timestamp enregistré donc facile pour appliquer n'importe quel calcul de période.

Petit nouveau ! | 8 Messages

18 juil. 2012, 22:28

OK pour le timestamp de dernière actualisation, j'avais déjà ça en tête pour mettre en bdd.
La question que je viens poser ici c'est comment mettre en place les tâches automatiques lorsque le joueur n'est pas connecté ?

ViPHP
xTG
ViPHP | 7331 Messages

19 juil. 2012, 09:44

En as-tu véritablement besoin avec un système de timestamp ? Telle est la question.
Sinon la réponse dépendra de ton type d'hébergement, si ce n'est pas un dédié c'est vers ton panel d'hébergement qu'il faut te tourner.
Si c'est un dédié, faut te connecter en ssh et le configurer toi même (à moins que tu n'ai installé un panel).

Petit nouveau ! | 8 Messages

19 juil. 2012, 12:17

En as-tu véritablement besoin avec un système de timestamp ? Telle est la question.
Sinon la réponse dépendra de ton type d'hébergement, si ce n'est pas un dédié c'est vers ton panel d'hébergement qu'il faut te tourner.
Si c'est un dédié, faut te connecter en ssh et le configurer toi même (à moins que tu n'ai installé un panel).
Ce n'est pas ma question... J'ai un dédié et je sais comment on paramètre une tâche cron. Mon souci c'est :
- est-ce qu'avec une tâche cron qui se lance toutes les minutes sur le serveur, ca ne va pas le surcharger si il y a 500 joueurs a updater dans la minute?
- et si il y a 2000 joueurs qui sont connectés en même temps, cela risque aussi de ralentir le serveur, et de causer des lenteurs d'affichage des pages pour les joueurs?
- j'imagine que dans ce cron, on va tester chaque seconde si dans la table des process il y a quelque chose à faire. si dans la seconde il y a 200 process à faire (par exemple), je doute que ces X tâches puissent être faites en 1 seule seconde, et dans ce cas si le joueur est connecté et que son compteur arrive à 0, j'ai bien peur que le cron ne soit pas synchronisé parfaitement avec la page du joueur, et là ca devient problématique... :cry: tu vois ce que je veux dire?

En tout cas merci à tous pour vos réponses!

ViPHP
xTG
ViPHP | 7331 Messages

19 juil. 2012, 15:42

Je pense justement avoir répondu à cette question dans mon premier message...
Solution : timestamp et mise à jour quand un utilisateur demande l'information

Petit nouveau ! | 8 Messages

19 juil. 2012, 15:46

OK, as tu une idée dans le cas du cron, sur la surcharge, et la synchro entre le compteur et le cron stp?

ViPHP
xTG
ViPHP | 7331 Messages

19 juil. 2012, 20:22

Je ne me suis jamais amusé à faire des tests absurdes non.
Et je ne pense pas que tu trouves quelqu'un sur ce forum qui se soit amusé à lancer un Cron toutes les minutes. ^^
Ce n'est clairement pas la technologie pour faire cela, donc faut pas chercher midi à quatorze heure.

Mais pour te rendre compte un peu tu peux faire un script en C ou tout autre qui tourne avec deux threads.
Tu prends une ressource quelconque que tu protèges avec une sémaphore.
Et regardes un peu le nombre d'accès possible par thread en une seconde.
Tu auras déjà une idée du temps d'accès sans aucun calcul ou traitement.
Sachant que pour tout traitement du peux multiplier par 10, voire par 100.
Et si tu inclus un accès SGBD, tu peux multiplier par 1000.

Un Cron est fait pour tourner en fond, mais faut pas oublier qu'il bouffe de la mémoire et du processeur.
Et ces choses là sont pas données sur un serveur, donc quand à parler de 2000 visiteurs à ce moment là...
C'est un serveur qui soit va fonctionner bizarrement sous la charge, soit qui va ramener les visiteurs à l'âge de pierre au niveau vitesse de navigation.
Et le pire qu'il puisse y avoir c'est la surcharge, à savoir une Cron qui se relance avant que sa précédente instance ne soit finie. En gros une boucle infinie surchargeant la mémoire.

Petit nouveau ! | 8 Messages

19 juil. 2012, 23:34

Sachant que pour tout traitement du peux multiplier par 10, voire par 100.
Et si tu inclus un accès SGBD, tu peux multiplier par 1000.
Pourrais tu préciser ce qu'on multiplie par 1000, et pourquoi ce chiffre? (désolé c'est un peu bête comme question mais j'aimerais comprendre)

ViPHP
ViPHP | 928 Messages

20 juil. 2012, 00:23

Bonsoir,

La problématique que vous avez là est typique des jeux vidéos PHP en temps réel (type Ogame par exemple). Il y a deux paramètres à prendre en compte pour déterminer la solution technique : le nombre de joueurs et la gourmandise des scripts qui seront exécutés.

A moins que votre jeu ne soit un énorme succès avec plusieurs centaines de joueurs par seconde, et à moins que le script qui réinitialise les objets ne soit gourmand, vous pouvez tout simplement vous contenter de loguer dans une table la liste des actions à faire en stockant : le nom de l'action, l'ID du joueur, l'heure à laquelle le script doit être exécuté. Ensuite à chaque chargement de page il suffit de lancer toutes les actions dont le timestamp enregistré dans la table est inférieur au timestamp du moment présent. Cette solution est largement possible pour un jeu assez modeste.

Après l'idéal c'est de n'exécuter les actions qu'à un moment précis. Par exemple si le joueur A attaque le joueur B, il ne suffit de lancer l'action "calculer le rapport de combat" qu'à ces moments :
- Si le joueur A veut consulter le rapport de combat
- Si le joueur B veut consulter le rapport de combat
- Si un tierce joueur attaque un de ces deux joueurs, il faudra dans ce cas que les troupes restantes de A ou B aient été mises à jours

ViPHP
xTG
ViPHP | 7331 Messages

20 juil. 2012, 08:45

Sachant que pour tout traitement du peux multiplier par 10, voire par 100.
Et si tu inclus un accès SGBD, tu peux multiplier par 1000.
Pourrais tu préciser ce qu'on multiplie par 1000, et pourquoi ce chiffre? (désolé c'est un peu bête comme question mais j'aimerais comprendre)
C'est un ordre de grandeur, pas une valeur réelle et fixe.

Eléphant du PHP | 190 Messages

20 juil. 2012, 15:47

et même s'il n'est pas connecté, le traitement se fait quand même.
Pourquoi alors que le joueur n'est pas la pour le voir ? A moins que tout les joueurs aient accès à tout les compteurs de tout les joueurs je ne vois pas l'utilité de cela. Et même si c'était le cas, il suffirait de traiter la demande uniquement lorsqu'elle est demandée.

Imagine que ton jeu rencontre un réel succès, avec des milliers de comptes dont des milliers inactifs, tu exécuterais des milliers de requêtes inutilement et chaque minutes en plus !

Petit nouveau ! | 8 Messages

20 juil. 2012, 15:50

@Zahnzao : tu as parfaitement raison, quelqu'un me l'a fait remarquer sur un autre forum, et après réflexion c'est la piste que je vais suivre.
Merci pour ta réponse!