FineMessageQueue

Présentation

Cette extension contient un objet dont le but est de gérer une file de message. Les files de messages facilitent la communications entre les différents modules d'une application.

Certains processus peuvent alors créer des messages qui sont ajoutés à la file.
En parallèle de cela, d'autres processus peuvent lire les messages. La lecture se fait suivant l'ordre dans lequel les messages ont été créés.

Les processus qui lisent les messages doivent se déclarer comme étant :

  • reader : Récupère le(s) prochain(s) message(s), sans en altérer le statut.
  • worker : Récupère le(s) prochain(s) message(s) et le(s) marque "en cours de travail".
  • eater : Récupère le(s) prochain(s) message(s) et les efface.

Lorsqu'un message a été marqu" "en cours de travail", il ne sera plus lisible par aucun autre processus.
Le processus "worker" qui l'avait récupéré doit explicitement demander à l'effacer une fois qu'il a terminé de travailler dessus.

Installation

Pour installer cette extension, téléchargez-la, puis placez le fichier FineMessageQueue.php dans le répertoire lib/ de votre site.

Une fois le fichier installé, vous devez créer une base de données nommée queue, qui va contenir deux tables (tQueue et tMessage). Il est important que les paramètres de connexion définis dans la configuration de votre site permette d'accéder à ces tables avec les droits SELECT, INSERT, UPDATE, DELETE.

Voici le code de création de la base et des tables :

CREATE DATABASE queue;
USE queue;

CREATE TABLE `tQueue` (
	`que_i_id`	INT UNSIGNED NOT NULL AUTO_INCREMENT,
	`que_s_name`	CHAR(25) NOT NULL,
	PRIMARY KEY (`que_i_id`),
	UNIQUE KEY `que_s_name` (`que_s_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `tMessage` (
	`mes_i_id`		BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
	`mes_d_creation`	DATETIME NOT NULL,
	`mes_t_update`		TIMESTAMP NOT NULL,
	`mes_e_status`		ENUM('pending','processing') NOT NULL DEFAULT 'pending',
	`mes_s_token`		CHAR(32) NOT NULL,
	`mes_s_content`		CHAR(255) NOT NULL,
	`que_i_id`		INT UNSIGNED NOT NULL DEFAULT '0',
	PRIMARY KEY (`mes_i_id`),
	KEY `mes_e_status` (`mes_e_status`),
	KEY `mes_s_token` (`mes_s_token`(5)),
	KEY `que_i_id` (`que_i_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Utilisation

Vous pouvez instancier directement l'objet \FineMessageQueue, en sachant qu'il ne fait partie d'aucun namespace, et qu'il faut lui passer en paramètre une instance de l'objet \FineDatabase :

$queue = new \FineMessageQueue($this->_db);

La première chose à faire après avoir instancier l'objet est de définir la file de message avec laquelle on va travailler. En effet, il est possible de créer autant de files que souhaité, en fonction des usages que vous en aurez.
Les noms des files de messages peuvent avoir jusqu'à 25 caractères de long.

$queue->setQueueName('imageProcessing');

L'ajout d'un nouveau message à la file se fait avec la méthode sendMessage(), qui prend en paramètre les données que vous souhaitez pouvoir récupérer à la lecture du message. Les données sont sérialisées en JSON.

$data = array(
	'id'	=> 12,
	'name'	=> 'john'
);
$queue->sendMessage($data);

Le moyen le plus simple pour récupérer un message est d'utiliser la méthode getMessage(). Elle retourne le prochain message de la file, en le marquant "en cours de travail". Plus précisément, la méthode retourne un tableau associatif qui comporte les clés 'id' (l'identifiant du message) et 'content' (le contenu transmis lors de la création du message).
Une fois que le message est traité, il doit être effacé en utilisant la méthode removeMessage(), en lui fournissant l'identifiant du message en paramètre.

$msg = $queue->getMessage();
doSomething($msg['content']);
$queue->removeMessage($msg['id']);

Il est possible de récupérer plusieurs messages d'un coup, ou bien de les récupérer en utilisant les rôles reader ou eater, en utilisant la méthode getMessages(), qui prend en premier paramètre le nombre de messages à récupérer, et en second paramètre le rôle à utiliser.

$list = $queue->getMessages(10, 'eater');
foreach ($list as $msg)
	doSomething($msg['content']);