4

I'm trying to send emails in a function within my views.py file. I've set up the email in my settings file in the same manner as here.

Python Django Gmail SMTP setup

Email sending does work but it takes several minutes to occur which my users have been complaining about. I am receiving a gethostbyaddress error in my var/log/mail.log file which I'll post here. I used to get nginx timeout errors but put "proxy_read_timeout 150;" into my /etc/nginx/sites-enabled/django file.

http://www.nginxtips.com/upstream-timed-out-110-connection-timed-out-while-reading-response-header-from-upstream/

This solved the timeout errors when interacting with the website but the emails still take several minutes to load. I'm using a digitalocean django droplet and this slow speed has occured on all my droplets.

Here's my view function

@login_required
def AnnouncementPostView(request, leaguepk):
    league = League.objects.get(pk=leaguepk)
    lblog = league.blog

    if request.method == 'POST':
        form = AnnouncementPostForm(request.POST)
        if form.is_valid():
            posttext = request.POST['text']

            newAnnouncement = Announcement(text=posttext, poster=request.user)
            newAnnouncement.save()
            lblog.announce.add(newAnnouncement)

            titleText = "%s Announcement" % (league.name)

            send_mail(titleText, posttext, settings.EMAIL_HOST_USER, ['mytestemail@gmail.com'], fail_silently=False)

       return HttpResponseRedirect(reverse('league-view', args=[league.pk]))
else:
    form = AnnouncementPostForm()

return render(request, 'simposting/announcementpost.html', {'form': form, 'league': league})

This has worked, the announcement is posted to the desired page and is even emailed, it's just a time problem, people have come to expect nearly instant emailing processes which makes the 2-3 minutes unacceptable, especially when signing up also causes the 2-3 minute wait.

One issue may be the fact that while trying to solve this issue with the DigitalOcean support team I changed my droplet name and the hostname to be the domain that I set up.

My current hostname and droplet name is mydomain.com. I have it setup that way in my /etc/hostname file. My /etc/hosts file looks like this

127.0.0.1 localhost.localdomain localhost mydomain.com
127.0.1.1 mydomain.com

My var/log/mail.log file responds with this whenever I try to send mail

Oct 6 16:13:24 "oldDropletName" sm-mta[13660]: gethostbyaddr(10.xxx.xx.x) failed: 1
Oct 6 16:13:24 "oldDropletName" sm-mta[13662]: starting daemon (8.14.4): SMTP+queueing@00:10:00

I hope this is enough information to help, it's been troubling for several weeks and usually I can either solve my problems by looking up stuff here or working with the support team but it's got us stumped. Thank you for taking the time to help!

Community
  • 1
  • 1
Michael Fox
  • 491
  • 5
  • 15

2 Answers2

21

Sending an email is a network bound task and you don't know how long it will take to finish exactly like in your case. Although there might be a latency in your network but it's better to do such task in an async fashion so your main thread is free.

I am using the following code in one my projects.

utils.py

import threading
from django.core.mail import EmailMessage


class EmailThread(threading.Thread):
    def __init__(self, subject, html_content, recipient_list, sender):
        self.subject = subject
        self.recipient_list = recipient_list
        self.html_content = html_content
        self.sender = sender
        threading.Thread.__init__(self)

    def run(self):
        msg = EmailMessage(self.subject, self.html_content, self.sender, self.recipient_list)
        msg.content_subtype = 'html'
        msg.send()


def send_html_mail(subject, html_content, recipient_list, sender):
    EmailThread(subject, html_content, recipient_list, sender).start()

just call send_html_mail from your view.

Chirdeep Tomar
  • 4,281
  • 8
  • 37
  • 66
  • This worked perfectly! I made a couple changes because it'll only ever be sent from one sender. I removed the 'sender' parameters from everything and in the EmailMessage function I put settings.EMAIL_HOST_USER instead. For future lookers I had to put from django.conf import settings at the top – Michael Fox Oct 06 '15 at 23:17
0

I am not particularly familiar with sendmail (I use postfix) but I would suspect this is almost certainly related to something with sendmail and probably not Django. The second log entry has "SMTP+queueing@00:10:00". and this link would indicate that sendmail takes a flag on startup to determine how often to process the mail queue. You may want to look around your init or wherever your startup scripts are and see how sendmail is configured. Also, if you are using Gmail you really can't control any delays on their end, so along with determining the configuration of your mail server, you'll need to check logs for when actions are actually occurring such as the mail being queued/sent. Is the time that line shows in your log from when the view was executed? If so, it is in the hands of sendmail.

Jmills
  • 2,414
  • 2
  • 19
  • 22