Bonjour à tous,

Je découvre actuellement Symfony, et en particulier le composent Messenger, que je trouve particulièrement pratique.
Dans le cadre de la création d'un petit site e-commerce, j'ai suivi différents tutoriaux pour mettre en place l'envoi d'email de confirmation d'une commande en asyncrone. En local, avec wamp64, c'est parfait. Tout fonctionne et les emails partent bien après la fameuse commande 'symfony console messenger:consume async -vv'.

Seulement, les choses se compliquent pour moi au moment de passer en prod. Peut-on vraiment utiliser ce composant quand on a un "simple" hébergement pro chez OVH ? Car on ne peut pas utiliser Supervisor ou systemd sur cet hébergement (ou alors, je ne sais pas comment faire). Je me suis dit, un peu naïvement, qu'appeller la commande à travers un controller que je mettrais en suite en cron suffirait. Alors j'ai écrit le code ci-après (d'après celui proposer à ce lien) :

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Annotation\Route;

define('STDIN',fopen("php://stdin","r"));

class MessengerConsumeController extends AbstractController
{

    /**
     * @Route("/mc", name="sendEmailOrderByBus")
     * Cette route sert pour mes tests à travers le navigateur
     * (mc = Messenger Consumme)
     */
    public function messengerConsume(KernelInterface $kernel): Response
    {
        $application = new Application($kernel);
        $application->setAutoExit(false);

        $input = new ArrayInput([
            'command' => 'messenger:consume',
            'async',
            '-vv',
        ]);

        // You can use NullOutput() if you don't need the output
        $output = new BufferedOutput();
        $application->run($input, $output);

        // return the output, don't use if you used NullOutput()
        $content = $output->fetch();

        // return new Response(""), if you used NullOutput()

        return new Response($content);
    }
}

Quand je test ce controller dans le navigateur, cela fonctionne 'presque' : les emails s'envoient bien, mais la page charge sans s'arrêter, jusqu'à finir sur un code 500.
En faisant un cron qui appelle ce fichier, les emails ne partent pas, j'ai directement un log d'erreur qui stipule que la page contient du code qui n'abouti pas.

En désespoir de cause, j'ai tester un cron sur ce fichier que j'ai mis dans le dossier public/

namespace App\Command;

use Doctrine\Bundle\DoctrineBundle\Command\Command;
use Symfony\Component\Process\Process;

class MessengerConsumeCommand extends Command
{
    protected static $defaultName = "messenger:consume";
    protected function configure()
    {

    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $process = new Process(['ls', '-lsa']);
        $process->start();

        foreach($process as $type => $data) {
            if ($process::OUT === $type) {
                echo "\nDebug : ".$data;
            } else {
                echo "\nErreur : ".$data;
            }
        }
        return 0;
    }
}

sans résultat (ni erreur ni réussite).

J'ai alors testé ça, placé à la racine du site

/** @var Composer\Autoload\ClassLoader */
require __DIR__.'/../vendor/autoload.php';

use Composer\Autoload\ClassLoader;
use Symfony\Bundle\FrameworkBundle\Console\Application;

$output = shell_exec('cd .. ;php bin/console --env=prod messenger:consume async --vv');
// Ici tu peux par exemple créer un ficher log dans /var/cron/ et mettre le résultat de output, mettre dans un try and catch et lever une exception etc...

exit;

Mais j'ai un log d'erreur qui me dit que la commande php n'est pas reconnu. Idem si je remplace 'php bin/console' par 'symfony console' : la commande symfony n'est pas reconnu.

Je précise bien que j'ai testé ces deux derniers fichiers en novice. Vous avez le droit de vous moquer de moi si c'était une idée ridicule d'amateur.

Bref, tout ça pour demander : est-il possible d'utiliser le composant Messenger avec un hébergement mutualisé ? Si oui, comment ? Ou bien le défi est-il trop grand, et ce composant reste le privilège de ceux qui ont un serveur dédié ?

En vous remerciant par avance de vos réponses,

Cordialement.

5 réponses


Bonjour,

Vraiment personne pour me renseigner ? Mince, j'espère que je n'ai pas questionné sur un sujet tabou :-/

Bonne journée.

Bonjour, je ne suis pas forcément le mieux placer pour répondre mais comme personne ne vous répond, je vais vous partager mes recherches car je suis dans le même cas que vous. Effectivement sur un hébergement OVH non dédié / non VPS nous ne sommes pas sudoer pour supervisor et n'avons pas accès à systemd. On ne peut donc pas mettre en place l'une des 2 solutions de processus proposées par la doc Symfony : https://symfony.com/doc/current/messenger.html.
Pour l'utilisation d'une CRON, je suis tombé sur cette proposition : https://www.devcoder.xyz/blog/516495/use-symfony-messenger-without-supervisor-3cl6, que je vais tester.
Il y a aussi l'option d'envoyer une 2ème requête asynchrone pour compléter la 1ere, sans en attendre la réponse, plutôt que de passer par un bus : https://afup.org/talks/3172-symfony-httpclient-vs-guzzle-vs-httplug.

Ceci dit votre appel a une commande par CRON me parait étrange. J'utilise un fichier bash (.sh) de ce type pour lancer mes CRON :

#!/bin/bash

export $(grep -v "^#" .env.local | xargs)

# Force source bash profile to update PATH
source ~/.bash_profile
source ~/.bashrc
ovhConfig

php ~/{site-dir}/bin/console {commande:name}

Bonjour,
Merci pour votre réponse, je commençais à croire que je n'étais pas au bon endroit pour espérer une petite porte de secours à mon problème.
Je testerai dès que possible les solutions que vous proposez (je suis actuellement sur un autre dossier) et vous ferez un retour.
Et puis, ne prenez pas en compte la commande CRON que j'avais posté. Je l'avais intégré dans mon sujet en désespoire de cause, mais elle n'a pas de sens. Merci d'avoir partagé votre fichier bash !
Vous souhaitant une bonne journée,
Cordialement.

Par contre, les deux liens que vous m'avez transmis sont les mêmes. C'est voulu ?

Non c'était un problème de CTRL V, j'ai mis à jour mon message