Vous n'êtes pas identifié(e).
Pour les temps, j'avais bien vu que c'était en minutes, très bien.
j'ai tout passé en smallint comme tu avais dis il y a qq post.
Ma fonction me donnait des valeurs qui me convenait, genre au bout de 20 minutes un pet avait parcouru 18000. (donc ma formule fonctionne)
Par qq ajustement, c'était lié au nom des champs pour collé a mes tables (par exemple: power_min => puissance_min)
Voila un nouveau résultat de la requete :
id_course id_pet ellapsed puissance_min dist_parcourue tps_restant
2 23 7.2500 5 0.03 12.7500
2 1 7.2500 5 0.02 12.7500
2 32 7.2500 5 -0.09 12.7500
DOnc puissance_min est bon, mais la distance parcouru non, et ca ne peut pas etre négatif
Je te colle aussi mes tables au cas ou et aussi pour voir ou j'en suis :
CREATE TABLE IF NOT EXISTS `course` (
`id_course` int(11) NOT NULL auto_increment,
`id_pseudo` int(11) NOT NULL,
`depart_theorique` datetime NOT NULL,
`depart` datetime default NULL,
`duree` smallint(3) unsigned NOT NULL,
`statut` tinyint(3) unsigned NOT NULL,
`nom_circuit` varchar(20) NOT NULL,
`level_min` tinyint(3) unsigned NOT NULL,
`level_max` tinyint(3) unsigned NOT NULL,
`ressource_type` tinyint(4) NOT NULL,
`ressource_quantite` int(11) NOT NULL,
`puissance_min` smallint(5) unsigned NOT NULL,
PRIMARY KEY (`id_course`),
KEY `statut` (`statut`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
--
-- Structure de la table `course_participant`
--
CREATE TABLE IF NOT EXISTS `course_participant` (
`id_course` int(11) NOT NULL,
`id_pet` int(11) NOT NULL,
`id_pseudo` int(11) NOT NULL,
PRIMARY KEY (`id_course`,`id_pet`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Structure de la table `pet`
--
CREATE TABLE IF NOT EXISTS `pet` (
`id_pet` int(11) unsigned NOT NULL auto_increment,
`nom_pet` varchar(40) NOT NULL,
`id_pseudo` int(11) unsigned NOT NULL,
`type_pet` tinyint(1) NOT NULL,
`level` tinyint(3) unsigned NOT NULL,
`xp` decimal(11,2) NOT NULL,
`sante` smallint(6) unsigned NOT NULL,
`strengh` smallint(3) unsigned NOT NULL,
`resistance` smallint(3) unsigned NOT NULL,
`endurance` smallint(3) unsigned NOT NULL,
`reactivite` smallint(3) unsigned NOT NULL,
`attaque` smallint(3) unsigned NOT NULL,
`defense` smallint(3) unsigned NOT NULL,
`agilite` smallint(3) unsigned NOT NULL,
`portage` smallint(3) unsigned NOT NULL,
`intelligence` smallint(3) unsigned NOT NULL,
`vie` smallint(3) unsigned NOT NULL,
`puissance` smallint(5) unsigned NOT NULL,
`oqp` tinyint(1) NOT NULL,
`aptitude` varchar(1) NOT NULL,
`nourriture` varchar(1) NOT NULL,
PRIMARY KEY (`id_pet`),
KEY `id_pseudo` (`id_pseudo`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=37 ;
Dernière modification par ebouilleur (22-11-2011 12:21:01)
Hors ligne
Bon,
Bien qu'il y ait encore des choses à dire sur la structure de tes tables (comme par ex la pertinence de id_pseudo), ton problème n'est pas là. Je vais aller donc à l'essentiel.
A mon avis le problème viens du fait que j'ai changé la précédence des opérateurs de ta fonction de calcul de distance.
Je m'explique.
Voici ton calcul PHP
et voici le calcul mysql
Donc les deux calculs n'ont effectivement rien à voir. Si tu veux le même calcul en mysql remets dans ta fonction mysql les parenthèses comme elles le sont dans ta fonction PHP et ton problème sera résolu.
++
Dernière modification par Jc (22-11-2011 13:24:51)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
OK,
Alors la procédure donne :
Et la résultat de la requete donne :
id_course id_pet ellapsed dist_parcourue tps_restant
2 1 11.0500 197.92 8.9500
2 23 11.0500 175.95 8.9500
2 32 11.0500 54.75 8.9500
Les distances ne sont pas identiques a ce que j'avais avant, mais comme ici tous les temps sont en secondes ça me semble normal. En tout cas les distances parcouru semblent logiques par rapport aux caractéristiques des pets!
Donc, me reste plus qu'a mettre ca en place et faire les crons pour le changement des status.
Pour stopper la course, tu penses que c'est mieux de faire comment? car faut l’arrêter a 20minutes pile (enfin si duree = 20)
En tout cas merci, ca m'a bien aider et j'ai appris plein de choses !
Et pour :
Bien qu'il y ait encore des choses à dire sur la structure de tes tables (comme par ex la pertinence de id_pseudo), ton problème n'est pas là. Je vais aller donc à l'essentiel.
Pour le moment le id_pseudo n'est pas utile, mais apres j'espere intégrer la possibilité d'avoir plusieurs pet pour le meme joueur, donc j'en aurais peut etre besoin...
Dernière modification par ebouilleur (22-11-2011 16:13:09)
Hors ligne
Bonjour,
Concernant id_pseudo c'est ce qu'il m'avait semblé comprendre. Si c'est le cas tu en as besoin dans aucune des trois tables si tu veux bien faire les choses
Pour arrêter la course, je vois deux systèmes (le 2 est meilleur mais requiert le 1^^).
1) Via ta requête de gestion de courses.
Pour cela tu as besoin tout d'abord dans les caractéristiques de tes circuits (de courses) de renseigner la distance à parcourir. A partir de là, vu que la requête te renseignes sur la distance parcourue, suffit d'y rajouter un test avec une colonne "gagné" par exemple en BOOL au cas où le pet a parcouru la distance impartie avant la fin des 20minutes. Mais cela sera inexact.
2) Si ta course est de type déterministe
Ton serveur est le seul à connaître ta fonction de calcul de distance. Si 3 pets donnés parcourent toujours la même distance en un temps donné, ton serveur peut déterminer à l'avance (au moment du départ) qui va gagner la course et quand (à la seconde prêt) en fonction de la distance à parcourir. Si le fait de gérer cela via un timer via une console adm de gestion de course est facile, ca l'est moins de l'intégrer côté serveur en automatique. La solution serait de le faire une fois la course finie même si la détection de fin de course est faite à un instant t+x. Une fois détectée, le serveur calcule de la même manière qu'il est capable de le faire à l'avance les temps et distances parcourues du vainqueur et les enregistre dans la table de course qui contiendra à ce moment les valeurs exactes.
C'est une idée comme une autre
Dernière modification par Jc (22-11-2011 18:09:11)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Bonjour,
Désolé je pensais avoir répondu hier soir, mais j'ai du oublier
Je ne vois pas trop comment faire pour savoir quelle est la distance a parcourir. C'est pour ca que j'avais décidé que la course serai gagné au bout de 20 minutes (car un pet niveau 1 et un autre niveau 30 ne vont pas parcourir la meme distance dans le meme temps. Surtout que pour le moment ma formule de calcule de distance est fixe, mais je dois l'améliorer pour donner un peu d'aléatoire (et aussi faire prendre en compte - je ne sais pas trop comment pr le moment - les différences entres les parcours - slalom, course de vitesse, etc)
Hors ligne
Bonjour,
Pour savoir quelle est la distance a parcourir, une simple colonne distance dans une table circuit ou dans la table course en attendant suffit.
Ensuite pour les différents types de parcours et pour te donner des idées, il faudrait définir un ensemble de points techniques avec leur quantité pour un parcours, sur lequels tu pourrais définir les caractéristiques minimum à avoir pour ne pas avoir de malus dans leur "négociation". Comme exemple de point techniques, "virage serré", montée, descente, endurance ( fatigue sur la longueur à courrir), enchainements de virages,... Comme exemple de critères pour "un virage serré" les critères determinant de base pourraient être la force puis l'agilité, etc... Ensuite à toi de construire un algorithme de calcul pour gérer tout cela..
++
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Je suis ok sur le principe de rajouter une colonne distance, mais je la fabrique comment cette valeur "distance"?
Hors ligne
Comme tu as envie dans un premier temps. Ensuite si tu appliques un système comme celui que je t'ai proposé, cela t'obligera sans doute à ne pas définir des distances trop longues pour les possibilités de pet, et d'introduire des niveaux de parcours en adéquation avec les niveaux des pets.
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Ouais ok... mais justement, je n'arrivais pas a fixer de distance a parcourir pour gagné, c'est pour ca que j'ai utilisé la durée... donc je ne vois pas d'autre moment que de faire un cron qui vérifie le valeur depart (table course) et quand datetime > depart + 20 min alors on passe la course au statut 3
La j'ai passé ma matiné a mettre en place tout ce qu'on a dit et a faire mon cron pour passé la course au statut 1 (presque fini)... je vais voir pour le reste, continuer de réfléchir
merci
Hors ligne
En fait vu l'ampleur de la tâche c'est de savoir par où commencer. Si ma proposition de plaît, commence par définir tes définitions, c'est à dire, contraintes, minimums, bonus, malus, ce qu'ils apportents ou font perdre par unité de valeur et une fois fini, construit ta formule de calcul, et on s'en fou si elle est longue. A partir de là la capactité des pets à parcourir une distance donnée t'apparaîtra comme une évidence ou presque^^.
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Oui elle me plait ta proposition, tu propose encore plus ce que j'avais pensé lol (car dans mon idée je pensais favoriser certes caractéristiques en fonction des parcours - c t plus simple ^^), et/mais comme tu dis c'est bcp de boulot...
Je pense que dans un 1er temps, je vais trouver un moment d'arreter la course sans connaitre de distance, mais je garde biensur tes remarques pour le futur
Sinon, j'essaye de récupéré la plus petite valeur de puissance dans la table pet (pour déterminer puissance_min de la course) mais j'y arrive pas
Un petit coup de pouce stp?
Edit, c'est bon j'ai trouvé ca donne :
merci
Dernière modification par ebouilleur (23-11-2011 17:49:59)
Hors ligne
Bon, voila le cron qui clos les inscription des courses, et passe celle-ci au statut=1
(cron lancer 10 minutes avant le départ des courses - d'ailleurs je me demande si ma requete ligne 37 ne serai pas a améliorer pour rendre ne compte ses 10minutes...)
if ($version == "") {
$version = $_GET['version'];
}
// on regarde quel version du cron lancer
if ($version == "beta"){
$chemin = "/home/ebouilleur/pet-racing/beta/";
} elseif ($version == "officiel") {
$chemin = "/home/ebouilleur/pet-racing/www/";
} else {
echo "<b>Bug, pas de version de sélectionné !!</b>";
exit;
}
$today_simple = date("Y-m-d");
$today = date("Y-m-d G:i:s");
$heure_depart = time() ;
include ($chemin.'bdd/bdd_beta.php');
include ($chemin.'fonctions/course.php');
include ($chemin.'fonctions/divers.php');
/********************* On regarde si il y a des courses au départ ********************/
$select = "SELECT id_course, UNIX_TIMESTAMP(depart_theorique) as depart_theorique FROM course WHERE depart_theorique<=NOW() AND statut='0' ";
//echo $select;
$result = mysql_query($select) or die ('Erreur selection des courses : '.mysql_error() );
while ($var_news = mysql_fetch_array($result)) {
$id_course = $var_news['id_course'];
$list_puissance = array();
// on vérifie qu'il y a plus de 4 participants (sinon on annule la course)
// a activer apres les test
$sql = "SELECT id_pet, id_pseudo FROM course_participant WHERE id_course='$id_course' ";
$req = mysql_query($sql) or die('Erreur SQL !<br>'.$sql.'<br>'.mysql_error());
if (mysql_num_rows($req) < 4){
while ($vars_suppr=mysql_fetch_array($req)) {
$id_pet_suppr = $vars_suppr['id_pet'];
$id_pseudo = $vars_suppr['id_pseudo'];
// la course est annulée
// on supprime les participants
$sqldel = "DELETE FROM course_participant WHERE id_pet='$id_pet_suppr' AND id_course = $id_course ";
mysql_query($sqldel) or die('Erreur SQL : effacement de sa participation !<br>'.$sqldel.'<br>'.mysql_error());
// on historise l'info
$commentaire = "Annulation de la course par manque de participant.";
send_sql("INSERT INTO course_histo VALUES ('$id_course','$id_pet_suppr','$id_pseudo_suppr','$commentaire','','$today') ","Historisation de l annulation de la course.");
}
$sqldel = "DELETE FROM course WHERE id_course='$id_course'";
mysql_query($sqldel) or die('Erreur SQL : effacement de la course sans participant !<br>'.$sqldel.'<br>'.mysql_error());
}
//
else
// la course a bien lieu
{
// on cherche la valeur de puissance_min des participants de cette course
$SQL2="select MIN(puissance) as puissance_min
FROM pet
WHERE id_pet IN (SELECT id_pet FROM course_participant WHERE id_course='$id_course')";
$sel2 = mysql_query($SQL2) or die('Erreur SQL liste participants !<br>'.mysql_error());
$var2=mysql_fetch_array($sel2);
$puissance_min = $var2['puissance_min'];
// on met les pet en oqp
$sqlUp = "UPDATE pet
SET oqp='4'
WHERE id_pet in (SELECT C.id_pet FROM course_participant AS C WHERE C.id_course='2') ";
mysql_query($sqlUp) or die('Erreur SQL : maj oqp pet départ course !<br>'.$sqlUp.'<br>'.mysql_error());
// on passe la course au statut 1 (=course inscription close)
$sqlUp = "UPDATE course SET statut=1, puissance_min=$puissance_min WHERE id_course='$id_course'";
mysql_query($sqlUp) or die('Erreur SQL : maj départ course !<br>'.$sqlUp.'<br>'.mysql_error());
}
}
echo "<b>Cloture des inscription aux courses réalisés</b>";
?>
Hors ligne
Bonsoir,
Que tu te compliques la vie!
1) Déjà, il y a une imprécision au niveau des status si tu veux faire quelque chose de plus efficace, il faudrait faire ceci
0 : course ouverte au inscription
1 : cloture des inscriptions 10 min avant le départ Prêt à partir -> cron qui vérifie le nb de joueur
2 : course en cours
3 : course terminée
4: course archivée annulée
5: course archivée courrue
2) Imprécision :
- Tu gères le temps au niveau php pour ta tâche CRON c'est bien, mais ton fichier cron doit être appelé il me semble dans deux contexte différents : pour les inscriptions et pour les départs/clotures. Donc il faut que tu retrouves ces deux contextes dans ton fichier et c'est justement au niveau de ta gestion temps PHP que tu vas le vérifier.
- Ta requête ligne 37 n'est pas correcte et source d'erreur. il faudrait plutôt un truc basé sur ce critère (je te laisse le faire je vais t'en laisser un peu^^)
Et qu'elle ait la signature suivante : id_course, nb_participants. Ensuite tu pourrais aussi pour contourner les problèmes de verous monter les résultats dans une table de type memory pour pouvoir faire tes mises à jours en une seule requête.
3) Ne supprime pas les participants et sert toi du champs statuts pour archiver tes courses. Tu as donc juste un update à faire dessus. De plus ton DELETE ligne 55 n'a pas besoin d'être dans une boucle car un simple
est équivalent. L'intérêt de passer par le statut pour l'archiver est aussi que ton DELETE te générera ici une erreur dans un contexte INNODB car ta table course_participants se retrouverait avec des enregistrements orphelins...
4) Les lignes 49 à 64 sont donc inutiles
5) Les tâches à éxécuter dans ce contexte sont donc terminées : on passe le statut à 4 quand count(id_pet)<4 et on le passe à 1 sinon. Fin de la tâche cron dans le contexte inscriptions.
Voilà pour le moment.
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Bonsoir,
Que tu te compliques la vie!
On me le dis souvent ^^
2) Imprécision :
- Tu gères le temps au niveau php pour ta tâche CRON c'est bien, mais ton fichier cron doit être appelé il me semble dans deux contexte différents : pour les inscriptions et pour les départs/clotures. Donc il faut que tu retrouves ces deux contextes dans ton fichier et c'est justement au niveau de ta gestion temps PHP que tu vas le vérifier.
Heu non, en fait je pensais faire un fichier cron par "étape", mais tu as surement raison, c'est mieux tout de le même.
- Ta requête ligne 37 n'est pas correcte et source d'erreur. il faudrait plutôt un truc basé sur ce critère (je te laisse le faire je vais t'en laisser un peu^^)
SELECT id_course FROM course WHERE UNIX_TIMESTAMP(depart_theorique) - UNIX_TIMESTAMP (NOW()) <=600 AND statut='0' ";
Et qu'elle ait la signature suivante : id_course, nb_participants. Ensuite tu pourrais aussi pour contourner les problèmes de verous monter les résultats dans une table de type memory pour pouvoir faire tes mises à jours en une seule requête.
Oula autant j'ai "entendu parler" de table mémory dans la config de phpmyadmin, autant je ne sais pas comment ca marche, ni ce que c'est (meme si le nom est parlant)
3) Ne supprime pas les participants et sert toi du champs statuts pour archiver tes courses. Tu as donc juste un update à faire dessus. De plus ton DELETE ligne 55 n'a pas besoin d'être dans une boucle car un simple
DELETE FROM course_participant WHERE id_course = $id_courseest équivalent. L'intérêt de passer par le statut pour l'archiver est aussi que ton DELETE te générera ici une erreur dans un contexte INNODB car ta table course_participants se retrouverait avec des enregistrements orphelins...
Oui t'as bien raison..
je pensais supprimer ce qui ne servait plus a rien de la table course et course_participant "pour y voir plus clair", mais autant garder tout là
Donc avec ce que je sais faire ca donne :
Hors ligne
Re,
C'est déjà beaucoup mieux, mais y a encore du taf^^
1)
en fait je pensais faire un fichier cron par "étape", mais tu as surement raison, c'est mieux tout de le même.
tu fais cela comme tu veux mais dans ton cas je reste convaincu que c'est en effet plus simple.
2) Une table memory c'est pas compliqué, en résumé c'est comme une table normale sauf qu'elle est gérée en mémoire plutôt que sur disque dur. C'est donc très rapide selon ce que tu souhaites faire ou selon tes contraintes de requêtage.
3) Vu que l'on est dans la partie des clôtures d'inscriptions, les lignes 29 à 33 n'ont rien à faire là car la course n'est pas encore lancée, sauf s'ils nont pas le droit d'aller pisser entre temps^^.
4) Ensuite pour information, lorsque tes circuits auront un niveau, ta puissance_min pourrait faire partie des critères requis pour accéder à la course et donc intervenir en plus du nombre de participants. Par contre ici, je n'en vois pas l'intérêt car la puissance min si elle est utilisée dans ton calcul de distance, elle est recalculée dynamiquement dans ta requête de gestion de course.. Tu peux donc supprimer je pense aussi les lignes 22 à 27 (la supprimer ici te fait économiser une requête serveur x la frequence d'interrogation de la tâche par jour sur le serveur).
5) Pense toujours à optimiser un max des tâches CRON pour la raison qui vient d'être évoquée.. Ca pourrait t'éviter de mettre un jour un serveur à genoux.
6) Pour les autres requêtes je pense que tu peux passer de 3 requêtes à 2.
7) Te reste à créer la condition PHP dans ton fichier pour éxécuter ce bloc lorsque cela est nécessaire.
++
Dernière modification par Jc (23-11-2011 23:49:52)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Bonjour,
2) Une table memory c'est pas compliqué, en résumé c'est comme une table normale sauf qu'elle est gérée en mémoire plutôt que sur disque dur. C'est donc très rapide selon ce que tu souhaites faire ou selon tes contraintes de requêtage.
Ok, mais je vois pas ou j'en aurais besoin...
3) Vu que l'on est dans la partie des clôtures d'inscriptions, les lignes 29 à 33 n'ont rien à faire là car la course n'est pas encore lancée, sauf s'ils nont pas le droit d'aller pisser entre temps^^.
bah c'est un peu ca ^^ et en plus faudrait aussi vérifier s'il n'est pas occupé ailleurs et dans ce cas le supprimé de la liste des participants (et donc a faire avant le calcule du nombre de participant - eh oui le pet ne se limite pas a faire des courses, ils peut aussi aller combattre lol)
4) Ensuite pour information, lorsque tes circuits auront un niveau, ta puissance_min pourrait faire partie des critères requis pour accéder à la course et donc intervenir en plus du nombre de participants. Par contre ici, je n'en vois pas l'intérêt car la puissance min si elle est utilisée dans ton calcul de distance, elle est recalculée dynamiquement dans ta requête de gestion de course.. Tu peux donc supprimer je pense aussi les lignes 22 à 27 (la supprimer ici te fait économiser une requête serveur x la frequence d'interrogation de la tâche par jour sur le serveur).
bah j'ai besoin de connaitre puissance_min puis le mettre dans la table course.... non?
5) Pense toujours à optimiser un max des tâches CRON pour la raison qui vient d'être évoquée.. Ca pourrait t'éviter de mettre un jour un serveur à genoux.
6) Pour les autres requêtes je pense que tu peux passer de 3 requêtes à 2.
7) Te reste à créer la condition PHP dans ton fichier pour éxécuter ce bloc lorsque cela est nécessaire.
Donc a priori, je ne pense pas réduire le nombre de requete.
Et je pensais appeler ce fichier toutes les 10 minutes (via crontab). Tu penses en plus que je dois faire un include de cette page quand un joueur va sur la page qui liste toutes les courses?
merci
Hors ligne
Bonjour
bah j'ai besoin de connaitre puissance_min puis le mettre dans la table course.... non?
Réponse: Relis bien
Jc a écrit:
4) Ensuite pour information, lorsque tes circuits auront un niveau, ta puissance_min pourrait faire partie des critères requis pour accéder à la course et donc intervenir en plus du nombre de participants. Par contre ici, je n'en vois pas l'intérêt car la puissance min si elle est utilisée dans ton calcul de distance, elle est recalculée dynamiquement dans ta requête de gestion de course.. Tu peux donc supprimer je pense aussi les lignes 22 à 27 (la supprimer ici te fait économiser une requête serveur x la frequence d'interrogation de la tâche par jour sur le serveur).
Ok, mais je vois pas ou j'en aurais besoin...
: Pour réduire tes requêtes.
bah c'est un peu ca ^^ et en plus faudrait aussi vérifier s'il n'est pas occupé ailleurs et dans ce cas le supprimé de la liste des participants (et donc a faire avant le calcule du nombre de participant - eh oui le pet ne se limite pas a faire des courses, ils peut aussi aller combattre lol)
Il te faut donc refaire ta requête initiale (plus bonne).
Et je pensais appeler ce fichier toutes les 10 minutes (via crontab). Tu penses en plus que je dois faire un include de cette page quand un joueur va sur la page qui liste toutes les courses?
C'est bien mais cela n'est pas suffisant. Car ton serveur a besoin de savoir à l'execution ce qu'il doit faire : valider les courses ou lancer/cloturer les départs.
Donc a priori, je ne pense pas réduire le nombre de requete.
C'est pas obligatoire mais cela serait mieux^^.
++
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Pour les tables memory, tu peux me donner un exemple concret de quand ca serai mieux pour moi d'en utiliser stp?
Sinon pour l'appel au fichier ailleur que dans le cron, j'arrive pas a en voir l'interet. Car les départs auront lieux à 10, 30 ou 50 minutes. Les clotures donc a 0, 20 ou 40minutes et les arrivées, 20 minutes apres les départs, soit 30, 50 et 10... donc un cron toutes les 10 minutes...
Car si j'appel mon fichier, genre include('cron_course.php'); dans ma page de récap de course ca va servir a rien de plus...
Enfin je ne saisi pas
Et sinon voila ce que donne mon cron_course.php pour le moment :
/*********************************
* On regarde si il y a des courses à mettre au statut 2 (soit en course)
* *********************************/
$select = "SELECT id_course
FROM course
WHERE UNIX_TIMESTAMP(depart_theorique) >= UNIX_TIMESTAMP(NOW() AND statut='1' ";
$result = mysql_query($select) or die ('Erreur selection des courses : '.mysql_error() );
while ($var_news = mysql_fetch_array($result)) {
$id_course = $var_news['id_course'];
// on passe la course au statut 2 (=course en cours)
$sqlUp = "UPDATE course SET statut=2, depart=NOW() WHERE id_course='$id_course'";
mysql_query($sqlUp) or die('Erreur SQL : maj départ course !<br>'.$sqlUp.'<br>'.mysql_error());
}
echo "<b>Course en cours...</b>";
/*********************************
* On regarde si il y a des courses à mettre au statut 3 (soit course terminée)
* *********************************/
$select = "SELECT id_course, duree, ressource_type, ressource_quantite
FROM course
WHERE (UNIX_TIMESTAMP(depart_theorique)+duree*120) >= UNIX_TIMESTAMP(NOW() AND statut='2' ";
$result = mysql_query($select) or die ('Erreur selection des courses : '.mysql_error() );
while ($var_news = mysql_fetch_array($result)) {
$id_course = $var_news['id_course'];
// on passe la course au statut 3 (=course fini)
$sqlUp = "UPDATE course SET statut=3 WHERE id_course='$id_course'";
mysql_query($sqlUp) or die('Erreur SQL : maj départ course !<br>'.$sqlUp.'<br>'.mysql_error());
// on calcule la distance parcouru par chaque pet
$sql="SELECT t1.id_course,t1.id_pet,t5.ellapsed,calc_dist(t2.endurance,t5.ellapsed,t4.puissance_min,t2.puissance,t3.duree) as dist_parcourue,
t3.duree-t5.ellapsed AS tps_restant, t2.nom_pet, t3.statut
FROM course_participant AS t1
LEFT JOIN pet AS t2 ON t1.id_pet=t2.id_pet
LEFT JOIN course AS t3 ON t1.id_course=t3.id_course
LEFT JOIN
(SELECT t1.id_course AS courseid, t1.id_pet, MIN(t2.strengh+t2.agilite+t2.intelligence) as puissance_min
FROM course_participant AS t1 left join pet as t2 on t1.id_pet=t2.id_pet GROUP BY t1.id_course) as t4 ON t1.id_course=t4.courseid
LEFT JOIN
(SELECT id_course, ((UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(depart)) /60) AS ellapsed FROM course) as t5 ON t1.id_course=t5.id_course
WHERE t3.statut=2 AND t3.id_course=$id_course
ORDER BY dist_parcourue DESC";
$result = mysql_query($sql) or die ('Erreur selection des courses : '.mysql_error() );
while ($var_news = mysql_fetch_array($result)) {
$sqlUp = "UPDATE course_participant SET distance='".$var_news['dist_parcourue']."' WHERE id_course='$id_course' AND id_pet='".$id_pet."' ";
mysql_query($sqlUp) or die('Erreur SQL : maj distance participants !<br>'.$sqlUp.'<br>'.mysql_error());
}
// on reverse les ressources gagnées pour les 3 1er pet (respectivement 60% - 20% - 10% de toutes les ressources "misées")
// a faire
// on passe les pet en non oqp (a faire aussi)
}
echo "<b>Course en cours...</b>";
bonne nuit
Dernière modification par ebouilleur (25-11-2011 17:23:02)
Hors ligne
Bonjour,
Pour les tables memory, tu peux me donner un exemple concret de quand ca serai mieux pour moi d'en utiliser stp?
L'exemple type puisque tu me le demandes c'est par exemple pour remplacer tes lignes 4 à 16 par seulement 4 requêtes. Tu me diras ca fait plus que ce qu'il y a déjà vu que j'en ai mis que deux!
Eh bien non, si tu comptes bien, et imaginons le cas d'une course avec 50 pets, tu auras : 1+50 requêtes dans ton exemple, et le but c'est d'optimiser en priorité tes tâches CRON.
Pour être concret, imaginons les deux requêtes suivantes simples
Si tu es sous INNODB et que tu souhaites transformer ces deux requêtes en une seule telles qu'elles, tu ne pourras pas (et sous MyISAM je te rassure, encore moins!) Pourquoi? Tout simplement car sur ton select ton moteur base de données vas poser un verrou en lecture (sur ta ligne en INNODB et sur ta table en MyISAM) qui t'empêchera de mettre à jour l'enregistrement en cours de lecture, alors que les deux requêtes séparées fonctionneront. Le but, pour contourner les verrous, est de créer une table de type MEMORY et de peupler ta table mémoire avec le résultat de ton select (en deux requêtes). Ainsi tu pourras mettre à jour ta table1 mais en lisant tes enregistrement à partir de table de type memory en une seule requête.
Sinon pour l'appel au fichier ailleur que dans le cron, j'arrive pas a en voir l'interet.
Tu m'as tout simplement mal compris, ou j'ai du mal m'exprimer.
Ton fichier cron actuel intègre 2 parties. La première vérifie les inscriptions et la 2e valide les départ/cloture des courses.
Actuellement si tu fais une tache cron toutes les 10minutes l'ensemble de ton fichier sera executé toutes les 10 minutes. Or la première partie n'a besoin que d'être éxécutée que 3 fois par heure et la 2e partie 3 fois par heure (au lieu de 6 fois par heure pour chaque partie actuellement). Il faut donc que tu intègres dans ce même fichier un test d'execution de chaque partie selon l'heure d'execution. C'est cela que je voulais t'expliquer en te disant
7) Te reste à créer la condition PHP dans ton fichier pour éxécuter ce bloc lorsque cela est nécessaire.
Pour le reste (la 2e partie) vu que c'est la première fois que tu me la montres, il y a autant de travail à faire dessus que ce que l'on vient de faire pour la 1ere partie. Et la je n'ai pas le temps, donc je reviens vers toi ce soir je pense.
Bonne journée.
Jc
Dernière modification par Jc (25-11-2011 18:04:25)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
OK je pense que je vois l'idée pour les table memory.
Faut que je me documente pour savoir comment gérer ca
Pour le cron, ok je vois mieux, je m'en occupe dans la soirée
Et pour la 2eme partie, c'est nouveau car je l'ai codé a la suite (faut aussi que j'avance dans mon dev)... heureusement que tu ne vois pas tout le code mysql de mon site... j'imagine du coup que tu tomberais en dépression
D'ailleurs le while (ligne 87 a 90) n'est jamais parcouru semble-t-il mais je ne comprend pas pourquoi
Merci
Dernière modification par ebouilleur (25-11-2011 17:42:50)
Hors ligne
Re,
Un exemple d'une de mes tables de production d'un client de type memory
Au niveau declaration ce qui change se situe uniquement au niveau ENGINE, rien de plus^^.
Pour ta boucle il se peut que cela vienne de ton $id_course tu ne l'as pas mis entre simple quotes comme sur les précédentes. Encore un conseil c'est de faire un $id_course = intval($var_news['id_course']); dès le départ comme ça tu peux les retirer dans toutes tes requêtes, elles n'en seront que plus performantes.
Sinon c'est qu'elle ne te retourne aucun enregistrement, en cas je la relis à tête reposée tout à l'heure.
++
Dernière modification par Jc (25-11-2011 18:07:33)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
OK je vais essayer d'en faire qqchose avec ces memory table demain matin ^^
Ma boucle, elle fonctionne.. c'est en effet qu'il n'y a pas d'enregistrement au statut 2, vu que juste avant je le passe au 3
Sinon pour appeler les parties de mon cron au bon moment, je propose un truc simple :
J'appel via crontab mon fichier toutes les 10minutes et ensuite en fonction des minutes je lance la partie qui va bien
ca va ou c'est trop simple?
Aller bonne nuit !
Hors ligne
Ton go_statut3, pour ce qu'il te sert^^ autant le retirer
Je sais plus si tu peux caler par exemple ton cron toutes les 10 minutes mais décalé de 10s. Si tu ne peux définir que par minute, je te propose de le faire à 1,11,21,31,41,51 sinon tu risques d'avoir des soucis avec ta tâche. A part tout ça, ça m'a l'air bien.^^
Bonne nuit
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne
Bonjour,
Sisi je peux faire tout ce que je veux, je peux donc décaller mon cron de 10s. ca change qqchose dans mon truc de $minutes?
Sinon, j'ai essayer de faire la 1er partie de mon cron avec des memory table.
J'ai surement mal fait, car ca me fait plus de code ^^ tu vas me dire ce que tu en penses
// création de la table momery pour les nb_participant
$requete="
CREATE TABLE IF NOT EXISTS `m_course_nb_participant` (
`id_course` int(10) unsigned NOT NULL , `nb_participant` tinyint(4) unsigned NOT NULL, `statut` tinyint(4) unsigned NOT NULL,
PRIMARY KEY (`id_course`))
ENGINE=MEMORY DEFAULT CHARSET=latin1
";
$result = mysql_query($requete) or die ('Erreur de création de la table memory du nb de participant : '.mysql_error() );
// création de la table momery pour les nb_participant
$requete="
CREATE TABLE IF NOT EXISTS `m_course_oqp_pet` (
`id_course` int(10) unsigned NOT NULL , `id_pet` int(10) unsigned NOT NULL , `oqp` tinyint(4) unsigned NOT NULL,
PRIMARY KEY (`id_course`), KEY `id_pet` (`id_pet`))
ENGINE=MEMORY DEFAULT CHARSET=latin1
";
$result = mysql_query($requete) or die ('Erreur de création de la table memory du nb de participant : '.mysql_error() );
while ($var_news = mysql_fetch_array($result)) {
$id_course = intval($var_news['id_course']);
$nb_participants = $var_news['nb_participants'];
$id_pet = intval($var_news['id_pet']);
// on vérifie qu'il y a plus de 4 participants
if ($nb_participants > 4){
// on ajoute a la table m_course_nb_participant le statut des pet
$oqp = 4;
send_sql("INSERT INTO m_course_oqp_pet VALUES ('$id_course','$id_pet','$oqp') ","Enregistrement du statut des pets.");
$sqlUp = "UPDATE pet
SET oqp='4'
WHERE id_pet in (SELECT C.id_pet FROM course_participant AS C WHERE C.id_course=$id_course) ";
mysql_query($sqlUp) or die('Erreur SQL : maj oqp pet départ course !<br>'.$sqlUp.'<br>'.mysql_error());
$statut = 1;
}else{
$statut = 4;
}
// on ajoute a la table m_course_nb_participant le nb de participant
send_sql("INSERT INTO m_course_nb_participant VALUES ('$id_course','$nb_participants','$statut') ","Enregistrement du nb de participant.");
}
// on met a jour les courses en fct du nombre de participant
$sqlUp = "UPDATE course AS C, m_course_nb_participant AS MC
SET C.statut=MC.statut
WHERE C.id_course=MC.id_course ";
mysql_query($sqlUp) or die('Erreur SQL : maj oqp pet départ course !<br>'.$sqlUp.'<br>'.mysql_error());
// on met a jour le statut du pet si il fait la course
$sqlUp = "UPDATE pet AS P, m_course_oqp_pet AS MP
SET P.oqp=MP.oqp
WHERE P.id_pet in (SELECT id_pet FROM m_course_oqp_pet) ";
mysql_query($sqlUp) or die('Erreur SQL : maj oqp pet départ course !<br>'.$sqlUp.'<br>'.mysql_error());
echo "<b>Cloture des inscription aux courses réalisés</b>";
Hors ligne
Bonjour,
Pour répondre à ta première question ca ne change rien à "ton truc de minutes" Ca change juste pour éviter les conflits de gestion. Donc 10s voire 5s c'est bien.
Alors excuses-moi mais ta première requête, que j'ai dû lire auparavant en diagonale n'est pas bonne non plus (normalement elle devrait ne pas fonctionner correctement si tu n'as pas d'erreurs, fais-moi un retour stp dessus).
Tu as changé la logique pour la résolution de ton cron, et ce n'est pas cela.
Ce qu'il faut faire en premier lieu c'est créer ta table de type memory (1 seule suffit) et d'y remonter toutes les informations que tu as besoin pour ton traitement.
Ensuite il te faut monter les informations dont tu as besoin dedans c'est à dire toutes les courses éligibles au prochain départ. A ce propos il faudra éviter d'y mettre le filtre WHERE opq=0 sinon tu risque de ne pas avoir toutes les courses. En effet, tu as choisi d'annuler les courses qui ont au moins un pet oqp au lieu d'exclure tout simplement le pet de la course préalablement au comptage des pets dispos au départ de la course.
Il te faut faire la requête suivante
Maintenant tu as toutes les courses éligibles au départ avec l'ensemble des pets associés respectivement à chaque course (avec leur statut (course+pet)) dans ta table memory
Les données sont donc maintenant prêtes à être mises à jour.
Note1:Je vais prendre le cas de figure ou l'on exclue le pet oqp^^ ne m'en veut pas trop. Pour cela dans la définition de ta table course_participant, il faut rajouter le champ statut_pet en tinyint unsigned not null avec 1 en valeur par défaut par ex qui signinie "faisant partie de la course". On reserve la valeur 2=exclu pour la course (et tu peux virer id_pseudo il sert à rien dans cette table.
Note2: Comme au moment où j'ecris je ne me rappele pas de ta codification de statut de pet, j'utilise ici pour l'exemple 0=libre; 1=oqp,
UPDATE course, pet, m_course
SET course.statut=1, pet.oqp=1 WHERE course.id_course=m_course.id_course AND pet.id_pet=m_course.pet_id AND MIN(m_course.nbparticipants)>=4
Alors pour le 2e update j'ai peur qu'en l'état cela ne passe pas et qu'il faille faire intervenir la table course_participant sur laquelle tu fais une jointure avec la table memory comme avec la première, et qu'ensuite que tu relies par une jointure avec la table course et pet.
L'idée est là.
Te reste encore une requête à faire pour annuler les courses qui n'ont pas au moins 4 pets au départ. Alors ca fera 5 (6 avec la suppression de la table memory à la fin) requêtes au lieu de 4, mais bon^^
++
Dernière modification par Jc (26-11-2011 17:36:31)
POO PHP+Ajax en MVC avec PDO et Bases de données épaisses : What else?
Hors ligne