From: joe on
Hi I wrote a function that uses
sendmail -oi -t -f
to send emails. It is currently taking a long time to send many
messages. Is there a way to speed this up?. Here is the code of the
function

sub sendEmail
{
my ($to, $from, $bcc, $subj, $message) = @_;
my $sendmail = '/usr/lib/sendmail';
my $line;
my @rawsender = $from;
open(MAIL, "|$sendmail -oi -t -f $rawsender[0]");

print MAIL "From: $from\n";

print MAIL "To: $to\n";
if (length($bcc) > 0){
print MAIL "Bcc: $bcc \n";
}
$message =~ s/\r/\n/g;


$message =~ s/!\*EMAIL\*!/$to/g;

$message =~ s/\r/\n/g;


my @lines = split("\n", $message);
print MAIL "Subject: $subj\n";
print MAIL "MIME-Version: 1.0\n";
print MAIL "Content-Type: text/html;\n";
print MAIL " charset=\"windows-1252\"\n";

foreach $line (@lines){
print MAIL "$line \n";
}
close(MAIL);
}
From: Tad McClellan on
joe <jcharth(a)gmail.com> wrote:

> sub sendEmail
> {
> my ($to, $from, $bcc, $subj, $message) = @_;
> my $sendmail = '/usr/lib/sendmail';
> my $line;


You should declare variables in the smallest possible scope.

For this variable, it should be declared in the foreach that
uses it as the loop control variable (below).


> my @rawsender = $from;
> open(MAIL, "|$sendmail -oi -t -f $rawsender[0]");


Why do you copy it to an array?

You should always, yes *always*, check the return value from open().

See also:

perldoc -q "pipe open"


> $message =~ s/\r/\n/g;

faster and more clear:

$message =~ tr/\r/\n/;


> my @lines = split("\n", $message);


Here you remove all of the newlines...


> print MAIL "Subject: $subj\n";
> print MAIL "MIME-Version: 1.0\n";
> print MAIL "Content-Type: text/html;\n";
> print MAIL " charset=\"windows-1252\"\n";
>
> foreach $line (@lines){

foreach my $line (@lines){

> print MAIL "$line \n";


.... here you put all of the newlines back.

What is the point of removing newlines only to put them back?

Do you really require a space character at the end of each line?

I don't see where you output a blank line to mark the end of the headers...


> close(MAIL);


You should check the return value from close() here too.


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.liamg\100cm.j.dat/"
From: joe on
Thanks for the tips. Is it possible to run the sub in a separate
thread and have multiple emails sent at the same time? If so how can I
do this? I am sending a few thousand messages so I am concern about
send mail not being able to handle this too.
From: Ron Bergin on
On Feb 8, 7:33 am, joe <jcha...(a)gmail.com> wrote:
> Thanks for the tips. Is it possible to run the sub in a separate
> thread and have multiple emails sent at the same time? If so how can I
> do this? I am sending a few thousand messages so I am concern about
> send mail not being able to handle this too.

I've never used it myself, but you might want to look at using
Mail::Bulkmail

http://search.cpan.org/~jimt/Mail-Bulkmail-3.12/Bulkmail.pm
From: joe on
I tested this script with only 10 messages and it worked but I am not
sure if it can handle a few thousands

use Thread qw(:DEFAULT async yield);

$thread = Thread->new(\&sendEmail($_,$in_sender,'',$in_subject,
$in_letter));