5

First of all, I would like to thank StackOVerflow and its users for helping me solve a number of technical problems. I created this account today since I could not see similar problem being addressed.

The problem - I am stuck with a problem with sending emails in PHP CodeIgniter. The function $this->email->send() is taking around 3-4 seconds each time to execute.

We have a social platform where users come and post things. Every time the user uploads a new update we want to send an email to him/her. The problem is the send email function takes around 3-4 seconds and we would love to bring it down under 1 second.

IS there any way wherein we can execute the send email process in parallel ? Say a python code which runs continuously to fetch new updates and send emails to those users. Any better method than that ?

Technology stack - PHP CI, MySQL, Apache, Windows

This is the email code that gets called on every new update -

$config = Array(
        'protocol'  => 'smtp',
        'smtp_host' => 'smtp.gmail.com',
        'smtp_port' => 587,
        'smtp_user' => 'mailid@gmail.com',
        'smtp_pass' => 'password',
        'mailtype'  => 'html',
        'charset'   => 'utf-8',
        'smtp_crypto' => "tls"
        );

$this->load->library('email', $config);
$this->email->set_newline("\r\n");
$this->email->set_mailtype("html");
$this->email->from('mailid@gmail.com', 'Support');
$this->email->to($this->session->userdata['email']);
$this->email->subject('You have posted a new update');
$this->email->message('Please login to check your new update. Do not reply to this email. For any issues reach out to email@emailid.com');

if (!$this->email->send())
{
    show_error($this->email->print_debugger());
}
else
{
    echo true;
}
Ganesh T
  • 81
  • 5
  • Hello, Well that would be great, if you find the answer let us know. But I think that may be a good waiting time, even when you send emails from either hotmail or gmail i think i takes longer than 1 minute. – Gerson E. Aguirre Sep 18 '17 at 07:01
  • I would suggest you to use asynchronous functions to send the email. This will help you to complete your logic faster and give quick response. For more information you can check https://stackoverflow.com/questions/13846192/php-threading-call-to-a-php-function-asynchronously – Nikhil Parmar Sep 18 '17 at 07:03
  • Thank you for your responses. Will try the async methods. – Ganesh T Sep 18 '17 at 07:12
  • 1
    How is the sending function working? When user update status in the same function it emails them? Like this way or you check if any new status later? – Imran Abdur Rahim Sep 18 '17 at 07:38
  • Yes. When user hits post, a function will be called. This function will insert into the database and then send the email. After wards on the success of this action, an ajax function is called to refresh the posts so that user sees the latest post. – Ganesh T Sep 18 '17 at 07:42
  • Then this is not the problem of sending. Your other function is making it slower. If i could see the exact code, i could understand – Imran Abdur Rahim Sep 18 '17 at 07:44
  • $clean = $this->security->xss_clean($this->input->post(NULL, TRUE)); $id = $this->update_model->insertUpdate($clean); I execute these two lines before sending the code. If I remove the email block this executes in less than 300ms. If i use the email block it takes ~4 secs – Ganesh T Sep 18 '17 at 07:48
  • You may also consider a job queue (such as [beanstalkd](http://kr.github.io/beanstalkd/)) and a (or later on multiple) worker process, that grabs the queued emails and sends them. This can help dealing with error scenarios (email server was not available), you can see what's in the queue, cancel jobs etc. – Stefan Sep 18 '17 at 07:48
  • It instantly insert into your database or taking some seconds? And user are getting mail after 3-4 secs ? – Imran Abdur Rahim Sep 18 '17 at 07:50
  • Thanks. I don't think the problem is queued emails. Just for sending one email too it takes ~4 secs. I guess the problem is making the smtp connection. That is taking time. If there is any way I can put that in background then I guess that should solve the problem. – Ganesh T Sep 18 '17 at 07:51
  • @Imran It instantly inserts in the database. Users receive the email instantly. The only delay is making the connection and sending the email. Once the action is performed I receive the email immediately. – Ganesh T Sep 18 '17 at 07:52
  • Got your problem – Imran Abdur Rahim Sep 18 '17 at 07:54

2 Answers2

1

It's my suggestion to store the emails in a database and send the emails using a cron job.
The uploading user should not wait to send emails one at a time .

If you need code for a cron job or an smtp mailer, add a comment to this answer.

SherylHohman
  • 16,580
  • 17
  • 88
  • 94
Vijay Sharma
  • 833
  • 8
  • 15
  • Thanks for the answer. The only problem with this approach is that I would need to continuously ping the database to check if there are any updates. That might make my database slower. Also, there is a possibility of deadlocks if number of users do updates simultaneously. – Ganesh T Sep 18 '17 at 07:11
  • retrieve email that not sent and set limit 10 , and set crone job time 30 sec . – Vijay Sharma Sep 18 '17 at 07:17
  • @user8625111 its working fine in my project. and delete emails that sent – Vijay Sharma Sep 18 '17 at 07:41
  • Can you elaborate a bit more on your solution. Suppose user A has updated his status as 'test update'. Then should i Store that in a table email_params with column 'to' as userA_email and column 'body' as 'test update'. Now do you suggest that I run a cron or python code that will fetch from this table and send email and then delete the entry ? – Ganesh T Sep 18 '17 at 07:55
  • @user8625111 ya its like that and if you attaching some file then save somewhere and better to run seperate cron to delete email , one in a day at some point of time – Vijay Sharma Sep 18 '17 at 08:00
  • @user8625111 sure – Vijay Sharma Sep 18 '17 at 08:03
1

If your function is working faster but email sending is slower, it must be problem for your smtp connection. Either your server is not much faster to connect SMTP quickly or the SMTP you are using bit slower to response. In that case, try with a gmail SMTP and see the result.

Imran Abdur Rahim
  • 407
  • 1
  • 10
  • 21