jueves, 14 de noviembre de 2013

Scheduled tasks in Symfony2: Symfony commands and Cron

Sometimes we need some tasks to be executed regularly. We could, for instance, want to send every midnight an email to every user who hasn't logged into our app for three days in order to provide him with a report of unseen notifications.  To get jobs like this done in a Symfony app we need two tools: Symfony commands and a task scheduler such as Cron in UNIX systems.

First of all we need to create a Symfony command which will execute the required functionality. We will create a folder named Command inside our Bundle (It will be on the same level as Controller or Resources folders). Then we create the command class, whose name must end with "Command". In this case I'll name it MyCommand.



As you can see MyCommand class extends ContainerAwareCommand class so that we can use the Service Container just by doing $this->getContainer(). This will give us access to any registered service, such as Doctrine Entity Manager or SwiftMailer.

As far as class methods are concerned, we have two methods: configure and execute. In configure method we will configure our command. We give it a name, in this case devness:my_command and arguments if necessary. Arguments can be required or optional, depending on the second argument of addArgument method (InputArgument::OPTIONAL or InputArgument::REQUIRED)

Execute is the method in charge of doing the hard work. As mentioned before we can get any service through the service container. Inside this method we could, for example, check for users who hadn't logged in for some time using Doctrine and then send them an e-mail. Now we have our Symfony command, so we will run it.

  • php app/console devness:mycommand --my_argument=value

  • Our argument is optional so we could omit it:
    • php app/console devness:mycommand

    Does it work? Perfect. Now we need this task to be run at some point in time, or regularly (every five minutes, every day, etc.). We will use Cron to schedule this task. You only will be able to go ahead on this tutorial if you run your Symfony app in a UNIX environment such as Linux or Mac OS X. It's not the purpose of this post to give a master class about Cron (I'm including a good reference at the end of the post). In short, we have a plain text file named crontab which we can edit by executing the following command:
    • crontab -e
    In my laptop this command opens the file using Vim. I don't really like Vim much (to be honest I don't even understand it, I should give it a try) so I execute it this way (nano editor):
    • EDITOR=nano crontab -e

    If we want our Symfony command to be run every minute we will ad the following line to the crontab:
    • * * * * * php /Path/to/SymfonyApp/app/console devness:mycommand --myargument=value

    Or If we wanted to execute it every two hours we could add this instead:
    • * */2 * * * php /Path/to/SymfonyApp/app/console devness:mycommand --myargument=value

    So that's it! We already have our Symfony command up and running. You can get some additional info on crontab format following this link

    No hay comentarios:

    Publicar un comentario