How can I throttle sending many emails?

AndyB

Well-known member
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.
 
You would need to paginate or use the deferred process system in some way.
 
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.
 
I think the real issue was PHP was timing out, so I put the following code before the loop:

set_time_limit(0);
 
Top Bottom