Re: [PHP] limiting the amount of emails sent at a time in a batch send



On Thu, Jul 31, 2008 at 4:24 PM, brian <php@xxxxxxx> wrote:
Andrew Ballard wrote:

On Thu, Jul 31, 2008 at 1:27 PM, brian <php@xxxxxxx> wrote:

Richard Kurth wrote:

I want to limit these script two send 100 email and then pause for a few
seconds and then send another 100 emails and repeat this tell it has
sent
all the emails that are dated for today. This script is runs by cron so
it
is running in the background.

How would I do this and is it the best way to do it. I am using swift
mailer to send the mail.

I think I would use limit 100 in the query but how would I tell it to
get
the next 100.

There's no need to limit the DB query, nor to track what's been sent by
updating the DB. Grab all of the addresses at once and let SwiftMailer
deal
with the throttling:

require('Swift/lib/Swift.php');
require('Swift/lib/Swift/Connection/SMTP.php');

/* this handles the throttling
*/
require('Swift/lib/Swift/Plugin/AntiFlood.php');


/* this holds all of your addresses
*/
$recipients = new Swift_RecipientList();


/* Grab the addresses from the DB (this is using MDB2)
*/
$result = ...

while ($row = $result->fetchRow())
{
$recipients->addTo($row['address'], $row['name']);
}
@$result->free();

try
{
$swift = new Swift(new Swift_Connection_SMTP('localhost'),
'your_domain');

set_time_limit(0);
$swift->log->enable();

/* 100 mails per batch with a 60 second pause between batches
*/
$swift->attachPlugin(new Swift_Plugin_AntiFlood(100, 60),
'anti-flood');

flush();

$message = new Swift_Message('your subject');

$message->setCharset('utf-8');
$message->setReplyTo(...);
$message->setReturnPath(...);
$message->headers->set('Errors-To', ...);

$message->attach(new Swift_Message_Part($plain_content));
$message->attach(new Swift_Message_Part($html_content,
'text/html'));

$num_sent = $swift->batchSend($message, $recipients, new
Swift_Address(..., '...'));

$swift->disconnect();

...


This is a rough example taken from my own script. This would need to be
modified if you're not sending the same message to all recipients, of
course. It's not clear to me from your example.

b


Nice! I'll have to look into this library some time. How do you
control it to prevent sending the same message though?

I'm not sure about that. Mine is for a newsletter (not personalised) so
Swift just needs a list of addresses. I can't remember if AntiFlood can be
used for many unique mails. I suspect that it doesn't.

I can't imagine
this is called from a web page, because I'm guessing it would take a
few minutes to finish.

cron. But, if you wanted it fired from an admin page (I can't imagine a good
situation where something like this would be public) you could add
ignore_user_abort() and then jazz up the page with some async JS.

If it's called from a cron job, don't you still

have to somehow flag the message as having been delivered so that the
next process doesn't come along and send the same thing all over
again?

Yeah, I just twigged to the fact that your messages are stored in the
database. This is some kind of messaging system? As opposed to a
newsletter-type thing, I mean. As above, I don't know that AntiFlood is
what you want. That's meant for multiple-recipient mails.

There's also a Throttler plugin, though, again, it's meant for batches.

You might also look at the IMAP functions. Instead of storing the messages
in the DB, you can let the MTA deal with pushing them out and cut Swift (and
the cro0n job) out of the loop.

b


The case I have in mind is for a newsletter, and in this instance they
are all the same. In this instance, I am limited by the host to 2500
messages/hour. (Originally it was 900). At this point, 2500 is more
than enough for this group, but I'd still like to play kindly with the
server resources since this is a shared host. I just set up a generic
message queue and dump mail there rather than sending it real time.
For now, all the messages in a given batch are the same, but I was
leaving flexibility in case I hit a situation where that changed.

It looks like this would work pretty well when I'm up for a rewrite. :)

I understand the general idea:

1. read message body from storage (file, database, etc.)
2. get result set containing addresses from database
3. build recipient list from result set
4. send everything to sendBatch()

It seems to me that step 5 still has to either (a) delete the message
body from storage or else (b) flag it as sent so that the next process
spawned via cron sees that there is no work to do and dies rather than
repeating the whole process again.

Andrew
.



Relevant Pages

  • Re: [PHP] limiting the amount of emails sent at a time in a batch send
    ... This script is runs by cron so ... I am using swift ... This is a rough example taken from my own script. ... used for many unique mails. ...
    (php.general)
  • Re: [PHP] limiting the amount of emails sent at a time in a batch send
    ... all the emails that are dated for today. ... I am using swift ... This is a rough example taken from my own script. ... I can't remember if AntiFlood can be used for many unique mails. ...
    (php.general)
  • ausgehende Emails mit vorhandenem Zipprogramm komprimieren
    ... um Emails vor dem Senden zu zippen. ... Das unten angegebene Script müsste bei einem anderen Zipper in Zeile ... Schon gezippte Mails werden unverändert durchgereicht. ...
    (microsoft.public.de.outlook)
  • Re: OT: spammers are using my domain again
    ... our virtual hosting servers and boom 150 returned emails from the ... Server load wasn't jumping ... Its a simple script that is written in php and can use a DB to retrieve ... they do anything) and the other hosting company that the file was ...
    (Fedora)
  • Re: Reading remote Session ID
    ... require that the IP that makes the request for the page be the same ... capability of the user, if it's a script the js will fail, so require ... I am using the free version of SPAMfighter for private users. ... It has removed 1384 spam emails to date. ...
    (alt.php)