JeuWeb - Crée ton jeu par navigateur
[Article] Utiliser l'asynchrone : pourquoi et comment ? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [Article] Utiliser l'asynchrone : pourquoi et comment ? (/showthread.php?tid=5697)

Pages : 1 2


[Article] Utiliser l'asynchrone : pourquoi et comment ? - Sephi-Chan - 18-09-2011

Lorsqu'on développe une application Web, on rencontre des tâches qui peuvent être longues et/ou qui doivent être planifiées.

Parmi les tâches longues à effectuer, on trouve notamment :
  • L'envoi de mails, qu'on utilise souvent lorsque le joueur s'inscrit, pour notifier à un joueur qu'il a reçu un message privé, pour annoncer à tous les joueurs une nouveauté majeur, etc.
  • L'envoi de requêtes HTTP, pour envoyer un fichier sur Amazon S3, récupérer les informations Facebook d'un membre, etc.
  • Le traitement d'images, pour générer un avatar, réduire la taille d'une image, etc.

Parmi les opérations à programmer dans le temps (à instant fixes ou cyclique), on trouve :
  • Le déclenchement d'événements comme les changements de tour, la distribution de ressources, etc.
  • Les tâches de maintenance, comme le rafraîchissement des caches, l'actualisation des pages de classement, la suppression des comptes inactifs.
  • La planification de tâches, comme la publication de news écrites à l'avance.

Quand on débute, on a souvent tendance à effectuer ces opérations au milieu du code, mais c'est une grave erreur ! Ça nuit aux performances et à l'expérience utilisateur !

Heureusement, il existe des solutions pour exécuter de telles opérations en tâche de fond.

Consultez l'article Utiliser l'asynchrone : pourquoi et comment ? sur le Wiki pour en savoir plus !

J'attends vos commentaires et vos questions ! Smile


RE: Utiliser l'asynchrone dès que possible - Hideaki - 18-09-2011

Très beau article, je pense qu'il sera utile pour certain.

Voici un complément :
En java c'est du natif par contre il est nécessaire de savoir utilisé les threads.
Voici un article parlant du problème asynchrone avec la résolution via le framework spring, spring permet aussi d'exécuter une tâche programmé année/jour/heure/minute/seconde via le le langage cron.

PS: La conclusion de l'article est intéressante Smile




RE: Utiliser l'asynchrone dès que possible - Sephi-Chan - 18-09-2011

Oui, ça ne sera pas du luxe quand je vois certaines horreurs ! Notamment dans les classiques système de ressources horaires. Hélas, certains font de la daube car ils ne veulent/peuvent pas louer de serveurs dédiés.

Allez, je continue ! J'avais laissé ça en plan avant de partir à l'arrache ! Je pense évoquer les points suivants :
  • Utiliser les crons, ça ne nécessite pas forcément de serveur dédié et ça peut libérer pas mal de ressources ;
  • L'utilisation de l'asynchrone permet de simplifier grandement le code : plus besoin de faire déclencher des événements à l'utilisateur selon certaines conditions (genre le premier joueur qui passe depuis une heure lance la mise à jour des ressources) ;
  • Expliciter les exemples donnés ;

Si vous avez d'autres points à explorer, n'hésitez pas à les signaler ! Smile

Je ne savais pas pour Spring, c'est intéressant. En cours, je n'ai bossé qu'avec Java EE (et EJB 3) et il fallait passer par les Executors ou par JMS, et ne pas toucher aux threads pour le faire. J'avoue ne pas avoir poussé l'investigation plus loin tant je trouvais cette techno lourdingue.


RE: Utiliser l'asynchrone dès que possible - srm - 18-09-2011

L'exemple de Facebook n'est peut-être pas bon ?
Car souvent c'est du Facebook connect et du coup ça doit être synchrone.


RE: Utiliser l'asynchrone dès que possible - Sephi-Chan - 18-09-2011

Tu peux récupérer plein d'informations de manière asynchrone ! Le flux du mec, les avatars de ses amis, etc.


RE: Utiliser l'asynchrone dès que possible - Dexyne - 19-09-2011


# Appelé avant l'exécution de la tâche, qu'elle ai réussi ou echoué.
def after(job)
end
Dans le commentaire ce serait pas plutôt "après l'exécution de la tâche" (et non avant) ?

Sinon c'est cool ça me servira surement un peu plus tard Smile.


RE: Utiliser l'asynchrone dès que possible - Sephi-Chan - 19-09-2011

Corrigé, merci ! Smile

J'ai ajouté un chapitre sur la mise en pratique concrète d'un cas (les changements de tours au sein d'un jeu) en suivant les approches synchrone, légèrement asynchrone et fortement asynchrone.

Ça peut en intéresser plus d'un car c'est capital d'apprendre à penser asynchrone.

N'hésitez pas à poser des questions ou a contribuer (à la discussion comme à l'article) !


RE: [Article] Utiliser l'asynchrone : pourquoi et comment ? - Xenos - 26-09-2011

Est-ce qu'il serait possible de simuler l'asynchronisation dans la page PHP, via la commande "header" de redirection (je ne suis pas certain du nom)?

L'idée serait, concrêtement, de tester si on a une simulation lourde à faire. Si oui, on utilise la requète header pour renvoyer l'utilisateur sur la même page, sans simulation, de sorte qu'il puisse jouer. Mais après l'appel à "header()", est-ce que le script php continue de tourner? Car si oui, il serait alors possible d'exécuter les codes de simulation, puis de clôturer le script sans rien envoyer au navigateur (puisque le client a déjà été redirigé).

Est-ce possible? Car alors, le serveur dédié n'est pas forcé, et il n'est pas utilie d'avoir un agent qui tourne en parallèle pour lancer les simulations quand il y en a besoin.


RE: [Article] Utiliser l'asynchrone : pourquoi et comment ? - niahoo - 26-09-2011

Hello, bienvenue parmi nous.

Alors, c'est quoi que tu appelles simulations au juste ?

Sinon, je crois bien que lorsqu'un navigateur reçoit un header de redirection il stoppe sa requête actuelle pour faire une requête sur la nouvelle URL. Mais peut-être que non.

Si oui, le serveur a les moyens de le savoir (connexion interrompue), et là il faut voir si php peut recevoir un signal

bon je viens de trouver ça, donc par défaut le script se stoppe mais on peut l'en empêcher.

Citation :Vous pouvez en outre décider si vous voulez que la déconnexion d'un client provoque l'arrêt de votre script. Il est parfois pratique que vos scripts continuent à s'exécuter jusqu'à la fin, même si le client n'est plus là pour recevoir les informations. Cependant, par défaut, le script s'arrêtera dès que le client se déconnecte. Ce comportement peut être modifié avec la directive ignore_user_abort dans le fichier php.ini ou bien avec la directive Apache php_value ignore_user_abort du fichier Apache httpd.conf ou avec la fonction ignore_user_abort(). Si vous ne demandez pas à PHP d'ignorer la déconnexion, et que l'utilisateur se déconnecte, le script sera terminé. La seule exception est si vous avez enregistré une fonction de fermeture, avec register_shutdown_function(). Avec une telle fonction, lorsque l'utilisateur interrompt sa requête, à la prochaine exécution du script, PHP va s'apercevoir que le dernier script n'a pas été terminé, et il va déclencher la fonction de fermeture. Cette fonction sera aussi appelée à la fin du script, si celui-ci se termine normalement. Pour pouvoir avoir un comportement différent suivant l'état du script lors de sa finalisation, vous pouvez exécutez des commandes spécifiques à la déconnexion grâce à la commande connection_aborted(). Cette fonction retournera TRUE si la connexion a été annulée.

source

Par contre :

Citation :Avec une telle fonction, lorsque l'utilisateur interrompt sa requête, à la prochaine exécution du script, PHP va s'apercevoir que le dernier script n'a pas été terminé, et il va déclencher la fonction de fermeture. Cette fonction sera aussi appelée à la fin du script, si celui-ci se termine normalement.

Si je lis bien, ça veut dire que ma fonction de fermeture se déclenche non pas lors de la coupure de connection mais lorsque je refais une requete, et là elle va être exécutée une seconde fois si le script se déroule en entier.
Non seulement ce n'est vraiment pas pratique, mais c'est carrément bancal.

Je crois surtout que la doc se goure et que la fonction est lancée lors de la fermeture de la connexion. ça me paraît mille fois plus logique.

Bon, en tout cas ton truc est possible, mais on ne sait pas si le navigateur va effectivement couper la connexion, et à mon humble avis ce n'est pas une bonne solution car tu dois lancer une première requête pour lancer la "simulation", et une seconde si tu veux récupérer un résultat.

Mettre en place un système de push revient plus ou moins au même (deux requêtes ou une seule (polling/long-polling) et est beaucoup plus pratique car on peut bâtir dessus des systèmes de communications plus forts et plus simples.

Et tout cela se fait sans serveur dédié. Je ne rejoins pas Sephi qui dit dans son article que le serveur dédié est obligatoire, notamment quand tu veux faire avec PHP. La pluspart des jeux que je vois ici proposent des scripts qui répondent instantanément à une action, ou qui regardent dans une base de données l'état général du jeu pour savoir ce qu'ils doivent faire.

Par contre je le rejoins quand il dit que c'est un must, car un daemon fait dans un langage performant t'offre le push, l'état du jeu et d'autres 'goodies' de façon simple. Pour le prix que ça coûte en général je n'ai pas hésité. T'en as qui vont claquer 200 € par mois pour leur passion, genre le ski nautique, et moi ça me revient à 85 € / an avec un VPS sympa.


RE: [Article] Utiliser l'asynchrone : pourquoi et comment ? - Sephi-Chan - 26-09-2011

Ça ne me paraît pas très fiable…

Un autre moyen de faire de l'asynchrone est d'utiliser le forking, mais ça nécessite l'extension PCNTL qui n'est pas disponible sur les serveurs mutualisés (que je connais). Et puis, ça a aussi des défauts. Cf. Process Forking with PHP et MySQL connections and PHP forked processes.

Enfin, le moyen le plus simple de commencer à travailler en asynchrone reste le Cron, qui lui est disponible sur les hébergements mutualisés (du moins chez OVH). Toutefois, un daemon est plus efficace, notamment concernant la gestion des erreurs au sein des tâches.
En revanche, je ne sais pas si la commande At est disponible sur les mutualisés.


Niahoo, pour quel VPS as-tu finalement opté ?