Laravel 5

Websocket et Jobs asynchrones

  • Avatar de AurélienMendes
    Membre depuis :
    03/09/2018
    Messages :
    8

    Salut à tous !

    J'aurais besoin de votre point de vue.

    Le pitch : j'ai un serveur websocket (socket.io + Redis) qui tourne et j'ai un Job (PHP) asynchrone que je lance au déclenchement d'un Event, qui lui-même lance une multitude de micro-Job asynchrones.
    Du coup, je veux informer mon utilisateur (qui a provoqué le lancement du Job) que le Job est en cours quand celui-ci commence à s'executer en affichant une pastille "Job en cours", et je veux enfin l'informer quand tous les mini-Job seront terminés, et ceci quelque soit la page sur laquelle sera et/ou ira l'utilisateur.

    Pour cela, aujourd'hui je "triche" en ayant un événements, Begin, qui est déclenché au début du code mon Job (=> socket.io écouteur pour afficher la pastille) et en écrivant dans mon cache (Redis aussi) des entrées du genre

    Cache::forever('mini-job.'.$uuid, 1);
    où chaque mini-job est identifié par un Uuid et que je supprime quand le mini-job est terminé.

    Comme ça à chaque chargement de page je peux faire un truc du genre

    var SHOW_NOTIF = \{\{ count(Cache::getRedis()->keys(Cache::getPrefix().'mini-job.*')) ? 'true':'false' \}\};
    (j'ai mis des \ pour pas que les moustaches soient interprétées ici)

    de sorte que si y'a encore au moins une entrée dans Redis alors ma variable SHOW_NOTIF est égale à true et j'affiche la pastille

    Je me suis quand même très rapidement dis que c'était pas top ... notamment parce que je dois explicitement faire appel à Redis (Cache::getRedis()) pour utiliser le wilcard (*) car cette fonctionnalité n'existe pas dans le Cache de Laravel.

    Donc je me disais que vous auriez peut-etre des idées à me soumettre pour faire ça autrement ... proprement ...

    Merci à tous !
    Auré

  • Avatar de Dom
    Membre depuis :
    17/07/2017
    Messages :
    37

    Et tu broadcast jamais ?

  • Avatar de AurélienMendes
    Membre depuis :
    03/09/2018
    Messages :
    8

    Si quand j'affiche la pastille lors du déclenchement de l'évenement Begin.

  • Avatar de Dom
    Membre depuis :
    17/07/2017
    Messages :
    37

    Et pourquoi tu broadcast pas à la fin pour lui dire que c'est terminé ?
    Tu chain tous les jobs et tu fais un dernier job qui event une fin ?
    https://laravel.com/docs/5.8/queues#job-chaining

  • Avatar de AurélienMendes
    Membre depuis :
    03/09/2018
    Messages :
    8

    Ah ouais ! Le chain je n'y avais pas pensé car j'utilise de design pattern Observer, donc je déclenche un event pour lancer un micro-Job.
    D'ailleurs, l'embêtant avec le chain, c'est qu'il faut attendre d'avoir fait tous les chain avant de dispatch ... en fait je suis dans une boucle et pour chaque itération je déclenche un event qui entraîne l'écoute du micro-Job.

    Mais l'idée me plait bien.

    En fait, pour tout dire, j'ai 2 cas de figure, l'un pour lequel ça sera parfait, l'autre pour lequel ce ne sera pas applicable je pense.
    Il s'agit de faire des post-traitements sur des fichiers après upload.
    Soit j'ai un zip, et alors je le dézip et pour chaque fichier à l'intérieur (le foreach) j'envoi un Job (micro-Job). Là dans ce cas du coup je pense que je peux faire ce que tu proposes.
    Soit dès qu'un fichier arrive sur le serveur si c'est pas un zip je lance le micro-Job directement et là par exemple si j'upload 500 fichiers, je veux savoir quand les post-process sont finis sur ces 500 fichiers, et là ça ne me semble pas applicable comme solution.

  • Avatar de AurélienMendes
    Membre depuis :
    03/09/2018
    Messages :
    8

    Par contre, le soucis du chain, c'est que les Jobs sont lancés à la chaines, donc pas moyen de faire des traitements en parallele pour accélerer.
    De plus, si un plante, tout s'arrête ...
    Du coup c'est quand même 2 contraintes trop fortes pour que cette solution me soit adaptée.

Vous ne pouvez pas répondre à ce sujet.