• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

How can I throttle sending many emails?

AndyB

Well-known member
#1
In my add-on Inactive Members:

http://xenforo.com/community/threads/inactive-members.69518/

I use the following code to send emails:

PHP:
foreach ($emails as $k => $v)
{
    // prepare $to variable
    $to = $v['email'];
   
    // replace {username} in message
    $nextMessage = str_replace('{username}', $v['username'], $message);               

    // username
    $username = $v['username'];
   
    // email
    $email = $v['email'];
   
    // define user variable
    $user = array(
        'username' => $username,
        'email' => $email
    );
   
    // prepare mailParams                   
    $mailParams = array(
        'user' => $user,
        'subject' => $subject,
        'message' => $nextMessage
    );
       
    // prepare mail variable
    $mail = XenForo_Mail::create('inactivemembers_contact', $mailParams);
   
    // send mail
    $mail->queue($user['email'], $user['username']);
}
It was reported to me that after about 5,000 emails being sent, the browser hangs with an error, sorry the error was not given.

My question, is there a way I can avoid the browser hanging by adding some code to throttle the emails?

Thank you.
 

AndyB

Well-known member
#4
Looking at the XenForo code:

1) I call the following code:

PHP:
$mail->queue($user['email'], $user['username']);
2) The following code is called in library/XenForo/Mail.php

PHP:
public function queue($toEmail, $toName = '', array $headers = array(), $fromEmail = '', $fromName = '', $returnPath = '')
{            
    if (!$toEmail)
    {
        return false;
    }

    if (!XenForo_Application::get('config')->enableMail)
    {
        return true;
    }

    if (!XenForo_Application::get('config')->enableMailQueue)
    {
        return $this->send($toEmail, $toName, $headers, $fromEmail, $fromName, $returnPath);
    }

    $mailObj = $this->getPreparedMailHandler($toEmail, $toName, $headers, $fromEmail, $fromName, $returnPath);
    if (!$mailObj)
    {
        return false;
    }

    return XenForo_Model::create('XenForo_Model_MailQueue')->insertMailQueue($mailObj);
}
3) Which calls the code in library/XenForo/Model/MailQueue.php

PHP:
public function insertMailQueue(Zend_Mail $mailObj)
{
    XenForo_Application::defer('MailQueue', array(), 'MailQueue');
    XenForo_Application::getDb()->insert('xf_mail_queue', array(
        'mail_data' => serialize($mailObj),
        'queue_date' => XenForo_Application::$time
    ));

    return true;
}
At this point it looks like the emails are put into xf_mail_queue table. But before that happens, I don't know what this code does:

PHP:
XenForo_Application::defer('MailQueue', array(), 'MailQueue');
It looks like the deferred system is already being used.
 

AndyB

Well-known member
#5
I think the real issue was PHP was timing out, so I put the following code before the loop:

set_time_limit(0);