<p>You are right about the Tasks running in the background. If the Task is just sending a few mails, it might be done before your site is loaded, thus creating this impression. </p>

<p><strong>Check:</strong></p>

<ul>
<li>Change the Batch Size of the <a href="https://github.com/victor-in/Craft-Mailer" rel="nofollow">Mailer plugin</a> to <code>1</code> and the waiting time to <code>120</code> seconds.</li>
<li>Change the <code>$user_criteria</code> to fetch 2 users.</li>
<li>Run your controller</li>
</ul>

<p>It should now take about 2 minutes for the Task to finish, if your site loads faster it was just an impression.</p>

<hr>

<p><strong>Code:</strong></p>

<p>You should however separate your code a bit more, because right now you are mixing <a href="http://buildwithcraft.com/docs/plugins/controllers" rel="nofollow">Controllers</a> and <a href="http://buildwithcraft.com/docs/plugins/services" rel="nofollow">Services</a>.</p>

<p>Your Service shouldn't output anything, it should just return a value, (e.g. <a href="https://php.net/manual/en/language.types.boolean.php" rel="nofollow"><code>boolen</code></a>), and your Controller should then output the message:</p>

<pre class="lang-php prettyprint-override"><code>Service {
    //Create Task etc...

    if ($itWorked == true) {
       return true;
    }
    else {
       return false;
    }
}

/* ------------------------ */

Controller {
    if ( FunctionService() ) {
       echo 'It worked';
    }
    else {
       echo 'Something went wrong';
    }
}
</code></pre>

<p>Also the "Make sure we kick the task off"-part, should go into your Service.</p>

<p><strong>P.S.</strong> I see you are using my plugin :), if you need any help, create <a href="https://github.com/victor-in/Craft-Mailer/issues?state=closed" rel="nofollow">an issue over on github</a>.</p>

CC BY-SA 3.0
2014-07-25T13:49:47.530Z
Thanks victor for the reply and for explaining to me about the best practices for controllers and services. Another piece of the puzzle just clicked into place :) Also, thanks for a great plugin, it works like a charm, very pleased with it. I'll be sure to head over github if I run into any issues in the future. Thanks again.
Dave Coggins
CC BY-SA 3.0
2014-07-25T14:06:22.090Z
Hi Victor, I've just tried out the settings you suggested and you are right, the emails are being sent as a background process as they should be, what I was experiencing was just an impression. I have noticed though the when I hit the controller I get a 504 Gateway Time-out before the controller returns with "emails sent". I guess this is not a massive deal because I'm going to be hitting this from a CRON job so as long as the task is triggered all should be well. I was wondering, do you know if it is possible to trigger the task from the command line rather than through the browser?
Dave Coggins
CC BY-SA 3.0
2014-07-25T14:11:54.150Z
I don't know why you get the time-out, maybe the output in the service causes this, but I'm not sure. I haven't used CRON yet, but the best way would be to trigger the Controller which then starts the Service and Task.
Victor
CC BY-SA 3.0
2014-07-26T00:51:11.977Z
I tracked down 504 gateway time-out to be to do with my nginx config. I fixed it by adding fastcgi_read_timeout 300; to the config.
Dave Coggins
CC BY-SA 3.0
2014-07-25T13:33:11.860Z
2014-07-25T13:49:00.980Z
2014-07-25T13:49:00.980Z
Victor
<p>I have my plugin working now so that I can email users who's accounts will expire in 7 days time. The users are being selected correctly and the emails are being sent as expected. However, the tasks don't seem to be running in the background. I was expecting that when I hit the controller the task will be triggered and the page would immediately return saying "emails sent". Instead it seems it waits until the emails are sent before returning "emails sent". I'm worried that if the number of emails is large the page will timeout before it completes. It was my understanding that tasks run as a background process but may I have miss understood. Can anyone explain them to me in more detail?</p>

<p>For reference here is the controller and the service of my plugin:</p>

<pre><code>class AcmeNotifications_NotificationsController extends BaseController
{

// let anyone run the controller actions
protected $allowAnonymous = array('actionSendEmail');

public function actionSendEmail()
{
    craft()-&gt;acmeNotifications_notifications-&gt;sendReminderEmail();

    //Make sure we kick the task off

    if (!craft()-&gt;tasks-&gt;isTaskRunning())
    {
        $task = craft()-&gt;tasks-&gt;getNextPendingTask();

        if ($task)
        {
            craft()-&gt;tasks-&gt;runPendingTasks();
        }
    }

    craft()-&gt;end();
}
}
</code></pre>

<p>and:</p>

<pre><code>class AcmeNotifications_NotificationsService extends BaseApplicationComponent
{
public function sendReminderEmail()
{
    //Get all users whos account will expire in 7 days
    $user_criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::User);

    $user_criteria-&gt;userExpiryDate = date('Y-m-d',strtotime("+7 days"));

    $users = $user_criteria-&gt;find();



    if($users){
        //Create array of user email addresses
        $user_emails = array();
        foreach ($users as $user) {
            $user_emails[] = array("to" =&gt; $user-&gt;email);
        }

        //Create an EmailModel
        $email = new EmailModel;

        //Set the global attributes 
        $email-&gt;fromName = 'Joe Blogs';
        $email-&gt;fromEmail = 'joe.blogs@example.com';
        $email-&gt;subject     = 'Your account will expire in 7 days';
        $email-&gt;htmlBody    = 'The message';

        //Create the RecipientsModel and add the user emails
        $recipients = new Mailer_RecipientsModel();
        $recipients-&gt;recipients = $user_emails;

        if( $recipients-&gt;validate()){
            //Create mailer task
            craft()-&gt;mailer_main-&gt;newMailer($recipients, $email); 
        }

        echo "emails sent";
    }
    else{
        echo "no emails to send";
    }
}


} 
</code></pre>

<plugin-development><tasks>
My tasks don't seem to be running as a background process
# My tasks don't seem to be running as a background process

(Asked by: username_0 on 2014-07-25)

I have my plugin working now so that I can email users who's accounts will expire in 7 days time. The users are being selected correctly and the emails are being sent as expected. However, the tasks don't seem to be running in the background. I was expecting that when I hit the controller the task will be triggered and the page would immediately return saying "emails sent". Instead it seems it waits until the emails are sent before returning "emails sent". I'm worried that if the number of emails is large the page will timeout before it completes. It was my understanding that tasks run as a background process but may I have miss understood. Can anyone explain them to me in more detail?
For reference here is the controller and the service of my plugin:
class AcmeNotifications_NotificationsController extends BaseController
{

// let anyone run the controller actions
protected $allowAnonymous = array('actionSendEmail');

public function actionSendEmail()
{
    craft()->acmeNotifications_notifications->sendReminderEmail();

    //Make sure we kick the task off

    if (!craft()->tasks->isTaskRunning())
    {
        $task = craft()->tasks->getNextPendingTask();

        if ($task)
        {
            craft()->tasks->runPendingTasks();
        }
    }

    craft()->end();
}
}

and:
class AcmeNotifications_NotificationsService extends BaseApplicationComponent
{
public function sendReminderEmail()
{
    //Get all users whos account will expire in 7 days
    $user_criteria = craft()->elements->getCriteria(ElementType::User);

    $user_criteria->userExpiryDate = date('Y-m-d',strtotime("+7 days"));

    $users = $user_criteria->find();



    if($users){
        //Create array of user email addresses
        $user_emails = array();
        foreach ($users as $user) {
            $user_emails[] = array("to" => $user->email);
        }

        //Create an EmailModel
        $email = new EmailModel;

        //Set the global attributes 
        $email->fromName = 'Joe Blogs';
        $email->fromEmail = 'joe.blogs@example.com';
        $email->subject     = 'Your account will expire in 7 days';
        $email->htmlBody    = 'The message';

        //Create the RecipientsModel and add the user emails
        $recipients = new Mailer_RecipientsModel();
        $recipients->recipients = $user_emails;

        if( $recipients->validate()){
            //Create mailer task
            craft()->mailer_main->newMailer($recipients, $email); 
        }

        echo "emails sent";
    }
    else{
        echo "no emails to send";
    }
}


}

**Tags:** plugin-development, tasks

---

## 1 answers

### Answer by username_1 on 2014-07-25. Score: 2 | Accepted answer

You are right about the Tasks running in the background. If the Task is just sending a few mails, it might be done before your site is loaded, thus creating this impression. 
Check:

Change the Batch Size of the Mailer plugin to 1 and the waiting time to 120 seconds.
Change the $user_criteria to fetch 2 users.
Run your controller

It should now take about 2 minutes for the Task to finish, if your site loads faster it was just an impression.

Code:
You should however separate your code a bit more, because right now you are mixing Controllers and Services.
Your Service shouldn't output anything, it should just return a value, (e.g. boolen), and your Controller should then output the message:
Service {
    //Create Task etc...

    if ($itWorked == true) {
       return true;
    }
    else {
       return false;
    }
}

/* ------------------------ */

Controller {
    if ( FunctionService() ) {
       echo 'It worked';
    }
    else {
       echo 'Something went wrong';
    }
}

Also the "Make sure we kick the task off"-part, should go into your Service.
P.S. I see you are using my plugin :), if you need any help, create an issue over on github.

> **Comments:**
> **username_0**: Thanks victor for the reply and for explaining to me about the best practices for controllers and services. Another piece of the puzzle just clicked into place :) Also, thanks for a great plugin, it works like a charm, very pleased with it. I'll be sure to head over github if I run into any issues in the future. Thanks again.  
> **username_0**: Hi Victor, I've just tried out the settings you suggested and you are right, the emails are being sent as a background process as they should be, what I was experiencing was just an impression. I have noticed though the when I hit the controller I get a 504 Gateway Time-out before the controller returns with "emails sent". I guess this is not a massive deal because I'm going to be hitting this from a CRON job so as long as the task is triggered all should be well. I was wondering, do you know if it is possible to trigger the task from the command line rather than through the browser?  
> **username_1**: I don't know why you get the time-out, maybe the output in the service causes this, but I'm not sure. I haven't used CRON yet, but the best way would be to trigger the Controller which then starts the Service and Task.  
> **username_0**: I tracked down 504 gateway time-out to be to do with my nginx config. I fixed it by adding fastcgi_read_timeout 300; to the config.  

---

