1. 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?

Discussion in 'XenForo Development Discussions' started by AndyB, Apr 1, 2014.

  1. AndyB

    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.
     
  2. Mike

    Mike XenForo Developer Staff Member

    You would need to paginate or use the deferred process system in some way.
     
    AndyB likes this.
  3. AndyB

    AndyB Well-Known Member

  4. AndyB

    AndyB Well-Known Member

    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.
     
  5. AndyB

    AndyB Well-Known Member

    I think the real issue was PHP was timing out, so I put the following code before the loop:

    set_time_limit(0);
     

Share This Page