View Full Version : Handling 100s of emails - process times out.

05-10-2004, 05:16 PM
I have a subscription service on a web site where users can sign up to be notificed via email when a particular item is uploaded.

Basically, we have about 15 spreadsheets on a web site which are uploaded via an admin interface. For each of these spreadsheets, there is a subsciption. A user signs up for that spreadsheet and everytime someone uploads the file all the users subscribed to that file, get an email with a link to that file.

So, all has been working well, until a few days ago. I have one subscription with a few hundred users (about 350) and the server admin has set the server timeout to 5 minutes (300 seconds). Well, it takes longer than 300 seconds for the script to email 350 + users. As a result, some don't get the notification. :(

I'm wondering if there is an easy way to send emails to users to reduce the time on the server.

Right now I'm sending the emails individually. Would it be better to send one email with a Bcc of all the receipients?

Is it possible to submit a process to run in the background and not worry about its completion. Just say to the script. Here ya go, email these 350+ addresses, and I'm going to move on.

Should I be looking a forking the email process?

Any ideas would be helpful

Here's the function I'm using to send the emails:

function sendNotifications($mID, $notes="",$notice="") {
$sql = "SELECT DISTINCT emailAddress FROM metricEmail WHERE metricID=".$mID." AND status=2";
$rs = getDBData($sql);
while($r = mssql_fetch_assoc($rs)) {
if($notice=="Yes") {
$title="Metric Mail Notification: ".$metricName." information update";
else {
$title="Metric Mail Notification: ".$metricName." has been uploaded";
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
$headers .= "From: Service Management<email@dot.com>\r\n";
$showUrl = "http://localhost/metrics/showMetric.php?id=".$mID."&source=metricMail";
$msg="<html><head><style type='text/css'>*{font-family:arial,sans-serif;}</style></head><body>";
if($notice=="Yes") {
$msg.="Below is a notice regarding the following Metric:<br /><br />";
else {
$msg.="The following Metric has been uploaded to our website:<br /><br />";
$msg.="\n<strong>Metric: </strong>".$metricName;
if($notes!="") {
$msg.= "\n<br /><strong>Notes: </strong>".$notes;
else {
$msg.="\n<br /><strong>Notes: </strong>No notes at this time";
$msg.="\n<br /><br />To view this metric, click on the link below:";
$msg.="\n<br /><a href='".$showUrl."'>".$showUrl."</a><br /><br />";
$msg.="\n<p>This and other metrics are available at our metrics web page at <a href='http://localhost/metrics/index.php'>http://localhost/metrics/index.php</a>.</p>";

$delUrl = "http://localhost/metrics/signUp.php?id=".$mID."&delete=".$r['emailAddress'];
$footer="\n\n\n<br /><br /><p style='font-size:0.8em;'>To remove yourself from this list, click on the link below:";
$footer.="\n<br /><a href='".$delUrl."'>".$delUrl."</a>";
mail($r['emailAddress'], $title, $msg, $headers);

05-10-2004, 09:40 PM
So this happens to you too? I thought I was the only one.

An idea I have had but have yet to test is to write the script to only do 20 at a time, then reload itself with a GET parameter to tell it where to start again.

Thus it can't time out as it would be loading itself brand new again, and once it realizes its at the end, it needs to know to quit.

But maybe, that will guide you in a direction that will fit your needs. And then you can tell me if any new problems arise before I attempt doing it.

05-10-2004, 10:19 PM
i agree with cpradio. hopefully you have an index number in all your tables. pass an GET variable, with the number to start with. (zero on the first pass). then structure your query dynamically, to only inlude rows with an index of $start to $start+20 (for instances). then header("Location: email.php?start=$next_start";

this is exactly what cpradio said, just more structered. (sp?)

05-10-2004, 10:22 PM
That was the hack I was thinking of implementing. I was just looking for a more elegant solution. Like fork n/20 processes where n is the total number of emails to send. Then everything has it's own limit and could (in theory) run faster. But I'm no expert on forking processes so I thought I'd ask everyone here.

If anyone has an elegant solution, I'd appreciate hearing from you.

05-11-2004, 05:41 PM
Forking is a great idea on machine level languages like C and C++, but when you work with an Interpreter like PHP, its much harder to implement a fork.

Infact, I cannot think of a way to do it without using a cronjob or a shell command...