MichaelMeyer has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I have a daemonized Script (using Daemon::Simple) that uses Mail::Sender to send mails, mostly with one PDF doc as attachment.

The script normally works fine, but once in while it hangs in the Attach method, and does nothing until I restart it.

Below is the method in the script, that sends the mails, it is called from the scripts main loop and uses an external SMTP server. Have you any suggestions?

sub send_statusmail ($$$$$) { my $retcode = (0==0); my $task_id = shift; my $task_info = shift; my $errmsg = shift; my $date_sent = shift; my $time_sent = shift; my $email_server = 'smtp.xxx.net'; my $email_login = 'xxx@xxxx.xx'; my $email_pass = 'xxxxxxxx'; my $email_from = 'noreply@xxx.xx'; my $base_dir = '/path/to/workdir'; my $tpl_email_feedback = "$base_dir/tpl/email_feedback_text.$servi +ce_name.tpl"; my $subj = "Ihr Sendebericht von xxxxxx.xx"; my ($to, $adminbcc); if ($errmsg !~ /Robinson/) { $to = $task_info->{'task_statusemail'}; $adminbcc = 'xxxxx@xxx.xx'; } else { $to = 'xxxxx@xxx.xx'; $adminbcc = 'xxxxx@xxx.xx'; $subj = "$service_name: Robinson"; $task_info->{'task_statusemail_doattach'} = 1; } my $body; my $sent = ($errmsg eq 'OK' ? 'erfolgreich':'NICHT'); # create mail body if (open FILE, "<$tpl_email_feedback") { my $linesep = $/; local $/ = undef; $body = <FILE>; close FILE; local $/ = $linesep; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = local +time($task_info->{'task_ctime'}); $mon = "0$mon" if $mon < 10; $mon = "0$mon" if $mon < 10; $mon = "0$mon" if $mon < 10; my $timestr = sprintf("%02d.%02d.%4d %02d:%02d:%02d", $mday, ++ +$mon, ($year + 1900), $hour,$min,$sec); $body =~ s/<-STATUS->/$sent/isg; $body =~ s/<-ERRORMSG->/$errmsg/isg; {'task_faxnummer_display'}/isge; $body =~ s/<-DATE->/$timestr/isg; $body =~ s/<-DATE-SENT->/$date_sent $time_sent/isg; $body =~ s/<-IP->/$task_info->{'task_ip'}/isge; my $attach_file = get_filename($task_id, $service_name); $Log->debug("found attach_file $attach_file"); $Log->debug("connecting to mail server..."); # now use Mail::Sender to send the status mail my $Sender = new Mail::Sender { 'smtp' => $email_server, 'auth' => 'LOGIN', 'authid' => $email_login, 'authpwd' => $email_pass, 'from' => $email_from, }; # log error and return false if not working $Log->debug(Dumper($Sender) . "\t" . $Mail::Sender::Error) && ret +urn (0==1) if not ref $Sender; $Log->debug("Creating Multipart mail..."); $retcode = $Sender->OpenMultipart({ 'to' => $to, 'bcc' => $adminbcc, 'subject' => $subj }); # log error and return false if not working $Log->debug(Dumper($retcode) . "\t" . $Mail::Sender::Error) && re +turn (0==1) if not ref $retcode; $Sender->Body({ msg => $body }); if ($task_info->{'task_statusemail_doattach'}) { $Log->debug("attaching file..."); $Sender->Attach( {description => 'Ihr Dokument', ctype => 'application/pdf', encoding => 'Base64', disposition => 'attachment; filename="Fax '.scalar localtim +e ($task_info->{'task_ctime'}).'.pdf"; type="PDF Document"', file => $attach_file }); } else { $Log->debug("NOT attaching file"); } $Log->debug("sending mail to $to ($task_id)"); # actual sending if (my $rc = $Sender->Close()) { $retcode = (0==0); $Log->success("sent mail for task $task_id"); } else { $retcode = (0==1); $Log->error("could NOT send mail for task $task_id $Mail::Send +er::Error\n".Dumper($rc)); } } else { $Log->error("cannot open file for reading: $tpl_email_feedback: +$!"); $retcode = (0==1) } return $retcode; }

Thanks in advance, Michael

Replies are listed 'Best First'.
Re: Mail::Sender hangs once in a while
by jethro (Monsignor) on Oct 20, 2009 at 12:34 UTC

    You seem to do a lot of logging but present no information what that tells you. What module parameters bring it to hang? Or is it independent of the parameters? Does it run in an endless loop or in a wait state?

    Check with a network sniffer if it tries to contact the SMTP server. Check with strace if it hangs in a system call. Check with the perl debugger, if and where it hangs in the perl code

      OK, you're right, I missed the logging information. Well, it tells me, that the script, WHEN it hangs, it hangs always between $Log->debug("attaching file..."); and $Log->debug("sending mail to $to ($task_id)");

      The whole thing runs in an endless loop. And I don't know howto debug this issue through the perl debugger or strace, as it only occurs once in a while

        You use
        filename="Fax '.scalar localtime ($task_info->{'task_ctime'}).'.pdf"; +type="PDF Document"', file => $attach_file
        Consider putting that concatenated value into a variable, checking for it's existence before you try to attach it, and displaying the filename in your $Log->debug("attaching file..."); statement.

        For that matter, what is the value of $attach_file, and how do the file and filename values interact?

Re: Mail::Sender hangs once in a while
by Anonymous Monk on Oct 20, 2009 at 15:04 UTC

    You can instruct Mail::Sender to produce a detailed logfile containing all the stuff it sends to the server and receives. Try that and see if it helps. Also, if you try to resend the very same PDF, does it hang again? Any change the file is still locked or something?

    Jenda

      That sounds very interesting. I will look into this and make Mail::Sender produce this log. Will tell you more, when the issue occured again after activating logging (probably tomorrow)

      thanks, Michael