Thread PHP dans Copix via HTTP

27/04/2008

Dans le précédent post Thread PHP dans Copix, j’ai présenté la méthode thread via pcntl. Cette méthode fonctionne convenablement sur Unix et en mode client console. Sauf que voilà, en mode WEB on ne pourra pas l’utiliser. Je me suis penché sur le sujet, et je n’ai trouvé qu’une seule et unique solution. J’ai donc recréé ma classe CopixThread dans un module et je vais vous expliquer comment je m’en sors. Sachez avant tout que **ça fonctionne très bien** et surtout je n’ai **plus de restriction en terme de plateforme, cela fonctionne partout** :).

Puisque nous n’avons pas un processus réél de PHP, nous ne pouvons pas créer un thread ou un fork. Par contre, quelque chose en amont utilise parfaitement les thread et on va s’en servir. Vous le connaissez, il se nomme **Apache**

Et oui, Apache permet de répondre simultanément à plusieurs clients. Nous allons donc faire en sorte que notre manager de thread puisse envoyer les demandes à Copix via Apache. En ouvrant des sockets, nous serons en mode “non bloquant” ce qui signifie que nous allons attendre nos données indéfiniement et sans coincer les autres sockets (du moins avec un timeout).

Après coup, nous continuerons notre processus. L’intérêt est simple: créer une structure de données et la faire travailler en parallèle d’autres tâches. Je vais vous montrer un exemple de traitement qui devrait travailler plus de 9 secondes mais ne saura finalement réalisé qu’en 5 secondes.

D’abord, présentons la classe Thread comme je l’ai implémenté. abstract class Thread { public $response; public abstract function process(); }

\$response contiendra le retour de process qui sera la méthode appelé lors de l’instanciation du thread.

Maintenant, voyons 2 nouvelles classes. Ces classes: ` <?php //test.class.php class Test extends Thread { function process(){ //on imagine 4 secondes de calcul sleep(4); return “Test: ok j’ai terminé’“; }

}

?> <?php //test2.class.php class Test2 extends Thread { public $flag=1; function process(){ //je prend 5 secondes de calcul sleep(5); return “Test2: ok j’ai terminé aussi’“; }

} ?> `

Mes classes prennent donc 4 secondes pour l’une et 5 secondes pour l’autre, ce qui fait au total 9 secondes de traitement. C’est dommage, car en effet, si on faisait tourner nos deux classes en parallèle, le traitement total ne serait que 5 secondes, c’est à dire le temps le plus long possible pour une classe.

Et bien avec le manager que j’ai créé, on va avoir à peu près ce résultat.

Voici un actiongroup qui va faire office de test. ` <?php class ActionGroupTest extends CopixActionGroup { function processDefault (){
//création du manager de thread $manager = _ioClass(‘ThreadManager’);

   //j'ajoute 2 threads
   $manager->add("test");
   $manager->add('test2');

   //et j'appelle l'éxecution
   $manager->execute();

   //juste question de présenter les réponses
   $ppo = new CopixPPO();               
   $ppo->MAIN = nl2br(str_replace(" "," ",var_export($manager->reponses,true)));
   return _arPPO($ppo,"generictools|blank.tpl");        
}

} ?> `

Le résultat est:

array (
  0 => 
  Test::__set_state(array(
     'response' => 'Test: ok j'ai terminé',
     'session' => NULL,
  )),
  1 => 
  Test2::__set_state(array(
     'flag' => 1,
     'response' => 'Test2: ok j'ai terminé aussi',
     'session' => NULL,
  )),
)

On a, dans nos réponses, les objets en retour. Nous voyons bien que la classe Test2 a toujours sa propriété “flag”, donc vous pouvez stocker ce que vous voulez à l’intérieur de votre classe.

Ayant activé le plugin Copix qui me donne le temps total de génération, je vois apparaître le temps **5.345**

  • - 5 secondes !!** et oui, je vous avais prévenu.

Alors le souci pour le moment c’est que mes classes qui héritent de Thread **ne peuvent pas** utiliser les sessions… L’idée c’est que le client n’est plus le navigateur, mais Copix lui même, depuis le serveur. De ce fait, la session n’est pas la même. J’aimerai trouvé le moyen de forcer cela, mais pour le moment ce n’est pas la question. D’ailleurs vous pouvez pallier le soucis en stockant les session dans votre classe de thread.

Un dernier point, la méthode add prend le chemin typique de copix module|nom de classe. Pour mes tests, les classes étaient dans le module Thread je n’ai donc pas eut à forcer le nom du module.

Voilà, quand j’aurai nettoyé tout ça, je le présenterai dans le tronc de Copix. Je pense qu’il sera de base dans Copix 3.1.

Ça peut vous intéresser aussi


Thread PHP dans Copix

Alors qu’on discutait sur le canal #fedora-fr de langages,...


Multiplexing ou Thread PHP sous Copix

Après moult développement en tout genre avec tests et montée ...


Optimisations Copix PHP et Apache

Les temps de réponse… Dieu sait à quel point cela ...


Nouveau serveur, nouveau copix

Et revoilà le blog ! Après avoir tant perdu mes ...

Merci de m'aider à financer mes services

Si vous avez apprécié cet article, je vous serai reconnaissant de m'aider à me payer une petite bière :)

Si vous voulez en savoir plus sur l'utilisation de flattr sur mon blog, lisez cette page: Ayez pitié de moi

Commentaires

Ajouter un commentaire

Ajouter un commentaire

(*) Votre e-mail ne sera ni revendu, ni rendu public, ni utilisé pour vous proposer des mails commerciaux. Il n'est utilisé que pour vous contacter en cas de souci avec le contenu du commentaire, ou pour vous prévenir d'un nouveau commentaire si vous avez coché la case prévue à cet effet.