25-11-2011, 01:29 AM
Déjà, il faut que tu fasses la part des choses entre Resque et Redis.
Prenons un exemple d'utilisation. Tu as un jeu qui envoie un mail à chaque membre d'une alliance quand un territoire de cette alliance subit une attaque. Pour éviter que le joueur qui lance l'attaque n'attende une plombe le chargement de la page (le temps qu'elle envoie tous les mails), on effectue ce travail en tâche de fond.
Du coup, quand un joueur va attaquer un territoire, on va dire à Resque de stocker quelques données dans Redis pour que les processus effectuent cette tâche dès qu'ils sont libres. On dit alors qu'on met un job dans la queue. Voici le code pour faire ça :
Cela permet d'ajouter à la queue "important_emails" une tâche qu'on identifie par le nom d'une classe et en lui transmettant quelques informations utiles.
L'avantage d'avoir plusieurs queues, c'est qu'un pourra lancer plusieurs workers, et les dédier (ou non) à une queue spécifique (comme la caisse "femmes enceintes" dans les magasins). Par défaut les workers consomment toutes les queues.
Il faut maintenant définir la classe job pour cette tâche. C'est simplement une classe qui dispose d'une méthode
Et voilà ! Maintenant les workers savent quoi faire !
Pour démarrer un worker (et il faut bien penser à le relancer quand on modifie le code source d'une classe qu'il utilise !), il suffit de lancer une petite commande :
Ici, la ligne définie deux variables d'environnement (qui seront seulement définies le temps de la commande) puis demande ensuite à l'intérpréteur PHP d'exécuter le fichier resque.php fourni avec Resque PHP. Ça va lancer un processus qu'on pourra kill quand on en aura marre.
La variable QUEUE permet d'indiquer la ou les queues à traiter : toutes, dans notre cas.
La variable APP_INCLUDE permet d'inclure un fichier. En l'occurrence, ce fichier fera des include des classes qu'on utilise dans notre tâche, établira la connexion à la base de données, etc.
Dès lors, dès que tu mettra un job en queue, un worker le traitera dès qu'il sera libre.
Voilà, voilà. Je peux difficilement être plus clair et concret. Partant de là, essaye de décrire ce que tu ne comprends pas et à partir de quand tu commences à être largué. En formulant clairement ce qui ne va pas, tu feras déjà un pas en avant.
S'il y a peu d'articles sur le sujet, c'est parce que l'utilisation de tâche de fond est une pratique un peu avancée et qui n'est visiblement pas très répandue dans la communauté PHP (malgré sa part de marché). On compte sur toi pour remédier à ça quand tu auras réussi.
Voici les solutions disponibles pour PHP dont j'ai entendu parler (je n'en ai utilisé aucune) :
- Redis, c'est un système de stockage en RAM qui tourne sur un serveur.
- Resque, c'est une library Ruby en 2 parties : une partie permet d'insérer des données dans Redis (mettre en queue) et une partie qui permet de lancer des processus qui vont consommer ces données depuis Redis (les workers).
- PHP Resque, c'est un portage de Resque en PHP. Il inclut un driver pour parler avec un serveur Redis.
Prenons un exemple d'utilisation. Tu as un jeu qui envoie un mail à chaque membre d'une alliance quand un territoire de cette alliance subit une attaque. Pour éviter que le joueur qui lance l'attaque n'attende une plombe le chargement de la page (le temps qu'elle envoie tous les mails), on effectue ce travail en tâche de fond.
Du coup, quand un joueur va attaquer un territoire, on va dire à Resque de stocker quelques données dans Redis pour que les processus effectuent cette tâche dès qu'ils sont libres. On dit alors qu'on met un job dans la queue. Voici le code pour faire ça :
$arguments = array(
"attacked_territory_id" => $attacked_territory->getId(),
"alliance_id" => $attacked_territory->getAlliance()->getId(),
"timestamp" => time()
);
Resque::enqueue('important_emails', 'SendAttackNotificationToAllianceJob', $arguments);
Cela permet d'ajouter à la queue "important_emails" une tâche qu'on identifie par le nom d'une classe et en lui transmettant quelques informations utiles.
L'avantage d'avoir plusieurs queues, c'est qu'un pourra lancer plusieurs workers, et les dédier (ou non) à une queue spécifique (comme la caisse "femmes enceintes" dans les magasins). Par défaut les workers consomment toutes les queues.
Il faut maintenant définir la classe job pour cette tâche. C'est simplement une classe qui dispose d'une méthode
perform
.
class SendAttackNotificationToAllianceJob {
public function perform(){
$alliance = Alliance::find($arguments["alliance_id"]);
$territory = Territory::find($arguments["attacked_territory_id"]);
$timestamp = $arguments["timestamp"];
AllianceMailer::deliverNotifyAttackOnTerritory($alliance, $territory, $timestamp);
}
}
Et voilà ! Maintenant les workers savent quoi faire !
Pour démarrer un worker (et il faut bien penser à le relancer quand on modifie le code source d'une classe qu'il utilise !), il suffit de lancer une petite commande :
$ QUEUE=* APP_INCLUDE=./config/init_worker.php php resque.php
Ici, la ligne définie deux variables d'environnement (qui seront seulement définies le temps de la commande) puis demande ensuite à l'intérpréteur PHP d'exécuter le fichier resque.php fourni avec Resque PHP. Ça va lancer un processus qu'on pourra kill quand on en aura marre.
La variable QUEUE permet d'indiquer la ou les queues à traiter : toutes, dans notre cas.
La variable APP_INCLUDE permet d'inclure un fichier. En l'occurrence, ce fichier fera des include des classes qu'on utilise dans notre tâche, établira la connexion à la base de données, etc.
Dès lors, dès que tu mettra un job en queue, un worker le traitera dès qu'il sera libre.
Voilà, voilà. Je peux difficilement être plus clair et concret. Partant de là, essaye de décrire ce que tu ne comprends pas et à partir de quand tu commences à être largué. En formulant clairement ce qui ne va pas, tu feras déjà un pas en avant.
S'il y a peu d'articles sur le sujet, c'est parce que l'utilisation de tâche de fond est une pratique un peu avancée et qui n'est visiblement pas très répandue dans la communauté PHP (malgré sa part de marché). On compte sur toi pour remédier à ça quand tu auras réussi.
Voici les solutions disponibles pour PHP dont j'ai entendu parler (je n'en ai utilisé aucune) :
- PHP Resque, dont on parle ;
- DJJob, qui est également un portage d'un library Ruby ;
- Gearman, que je ne connaissais pas jusqu'à aujourd'hui ;
- Zend Server Job Queue, qui est payant ;