4

I have a batch email process that sends about 30,000 email messages. I have ran into a strange problem where it gets to about 85% completion of the process and then the email start failing with the message Could not execute: /usr/sbin/sendmail I am using a library called PHPMailer 1.73 and the relevant code where the error message comes from is

if(!@$mail = popen($sendmail, "w"))
{
    $this->SetError($this->Lang("execute") . $this->Sendmail);
    return false;
}

The value of $sendmail is of the form: /usr/sbin/sendmail -oi -f support1@example.com -t

I have set_time_limit(0); so the script will not timeout.

Is there anyway to figure out why all of a sudden popen() starts failing? Could the OS be running out of file descriptors or some other limit being reached?

How should I resolve this? Should I have it sleep and then retry the popen() several times before failing?

Update: Thanks to the suggestion of Marko to check out proc_open() I found on the proc_open documentation a comment that if it returns FALSE it probably means that you ran out of file descriptors or you are out of memory. I found that my process was taking 20G of memory. But how could it take that much memory if memory_limit is set at 64M? Well, it seems that running external programs with exec(), popen() or proc_open() do NOT count against PHP's memory limit. See this SO question for more info on that, Debugging memory usage in mod_php. I'm still not sure how this is happening but I suspect some sort of memory leak.

In summary, popen() and proc_open() can return FALSE if you are out of file descriptors or out of memory.

Community
  • 1
  • 1
ejunker
  • 10,816
  • 11
  • 41
  • 41
  • Is your server configured with a maximum amount of smtp relays per hour/day? What is your script execution timeout set to? – 65Fbef05 Apr 06 '11 at 19:42
  • Could be running out of PIDs as well. older unix boxes (linux especially) had a ceiling of 2^16 pids. 30,000 emails sounds like it could be getting close to that, with regular system processes included. Though, I'd hate to see what the system load would b elike with 30,000+ sendmail instances chugging away. – Marc B Apr 06 '11 at 20:23

1 Answers1

2

I would recommend to use proc_open instead. It is slightly more complex to use, but gives you access to stdout and stderr. The messages on this two pipes will save you a lot of debugging time.

How to use, just read the examples and comments in the PHP documentation.

Marko
  • 514
  • 1
  • 4
  • 16