I use SwiftMailer to send emails from a gearman worker process. I'm using the Swift_SmtpTransport
class to send emails.
The problem is that if this worker process stays idle for sometime, the SwiftMailer smtp connection times out. Now when the next job arrives, SwiftMailer fails to send emails as the connection has been timed out.
Ideally, I would want to close the smtp connection after every job. I'm unable to locate a api in the class which does this specifically. Neither does unset()
object works since this is a static class.
When pipe is broken $mailer->getTransport()->stop() will fail as well. And due to this error transport cannot be stopped. The workaround is
I'm running a worker in an infinite loop using Swiftmailer and AWS SES I was getting the error:
Solution for my script:
I send mails in a loop and I was catching the
Swift_TransportException
and creating a new instance ofSwift_Mailer
but it wasn't the right fix: the problem is the transport, not the mailer. The solution is to issue an explicit call toSwift_SmtpTransport::stop()
:This way, Swift detects the mailer is stopped and starts it automatically, so it recovers correctly from communication errors.
I got the same exception with symfony2 command line while sending lots of emails using SwiftMailer and AWS SES.
I could fix my issue by starting and stopping the transport layer each time. Look at my blog post for more details: http://www.prowebdev.us/2013/06/swiftmailersymfony2-expected-response.html
There is a rude option: stop the transport explicitly. On subsequent calls of the method sendMail, SwiftMailer will check whether the transport is up (it is not, now) and start it again. IMNSHO, SwiftMailer should intercept the SMTP timeout and reconnect automatically.But, for now, this is the workaround: