2014-09-14 6 views
2

J'ai un serveur smtp threadé qui prend 20 secondes supplémentaires pour s'arrêter sur Linux (Ubuntu 14.04 et Fedora 20) que sur OS x (10.8).Différence de comportement étrange entre linux et os x avec smtpd fileté dans Python 2.7

from email.parser import Parser 
from smtpd import SMTPServer as StdLibSmtpServer 
from smtplib import SMTP 
from threading import Thread 
import asyncore 
import re 
import select 
import logging 
import os.path 
import datetime 
import json 
import random 
from socket import gethostname 
class SmtpServer(StdLibSmtpServer, object): 
    def __init__(self, listen='localhost', port=10025, 
      forward_address='localhost', forward_port=10026): 
     super(SmtpServer, self).__init__((listen, port), None) 
     self.forward_address = forward_address 
     self.forward_port = forward_port 
     self._thread = None 
     self._smtp = SMTP() 
     self._should_re_raise_exceptions = False 
    def start(self): 
     if self._thread: 
      raise Exception("Already running") 
     logging.debug("Starting up") 
     self._thread = Thread(target=self._thread_func) 
     self._thread.daemon = True 
     self._thread.start() 
     logging.info("Started") 
    def stop(self): 
     if not self._thread: 
      raise Exception("Not running") 
     logging.debug("Stopping") 
     self.close() 
     self._thread.join() 
     self._thread = None 
     logging.info("Stopped") 
    def _thread_func(self): 
     try: 
      asyncore.loop() 
     except select.error: 
      pass # socket was closed, we are shutting down 

Il arrive à la ligne self._thread.join(), et je ne peux pas à comprendre pourquoi.

Des conseils sur la façon de résoudre ce problème plus loin? je lance le fichier en faisant:

from test import SmtpServer 
serv = SmtpServer() 
serv.start() 
serv.stop() 

Le serv.stop() est la partie qui est beaucoup plus lent sur linux.

+1

Essayez de définir une valeur de délai à 'self._thread.join()' - c'est-à-dire 'self._thread.join (timeout = 0.5);' –

Répondre

1

Il s'avère que la cause première était asyncore.loop() nécessitant un timeout sur les systèmes qui utilisent select au lieu de epoll. Un grand merci à @binarydud pour son aide. Il s'avère que la définition d'un délai d'attente court sur le thread.join fonctionne également, mais cela peut entraîner l'utilisation de l'asyncore.

Questions connexes