이것은 이전에 대답 한 질문과 관련이 있습니다. Logging SMTP connections with Twisted. ConsoleMessageDelivery의 각 인스턴스에서 데이터베이스 리소스를 만들면 소켓을 닫을 때 정리해야합니다. DenyFactory라는 WrappingFactory가 있고 DenyFactory.unregisterProtocol 메서드는 소켓을 닫을 때 호출되지만 파괴되는 ConsoleMessageDelivery 인스턴스에서 생성 된 리소스에 액세스하는 방법이 없습니다. ConsoleMessageDelivery에서 del() 메서드를 시도했지만 결코 호출되지 않았습니다. 이 시나리오에서 리소스를 정리하는 가장 좋은 방법은 무엇입니까?Twisted Python의 SMTP 모듈을 사용한 리소스 정리
class ConsoleMessageDelivery:
implements(smtp.IMessageDelivery)
def receivedHeader(self, helo, origin, recipients):
myHostname, clientIP = helo
headerValue = "by %s from %s with ESMTP ; %s" % (myHostname, clientIP, smtp.rfc822date())
# email.Header.Header used for automatic wrapping of long lines
return "Received: %s" % Header(headerValue)
def validateFrom(self, helo, origin):
# All addresses are accepted
return origin
def validateTo(self, user):
if user.dest.local == "console":
return lambda: ConsoleMessage()
raise smtp.SMTPBadRcpt(user)
class ConsoleMessage:
implements(smtp.IMessage)
def __init__(self):
self.lines = []
def lineReceived(self, line):
self.lines.append(line)
def eomReceived(self):
return defer.succeed(None)
def connectionLost(self):
# There was an error, throw away the stored lines
self.lines = None
class ConsoleSMTPFactory(smtp.SMTPFactory):
protocol = smtp.ESMTP
def __init__(self, *a, **kw):
smtp.SMTPFactory.__init__(self, *a, **kw)
self.delivery = ConsoleMessageDelivery()
def buildProtocol(self, addr):
p = smtp.SMTPFactory.buildProtocol(self, addr)
p.delivery = self.delivery
return p
class DenyFactory(WrappingFactory):
def buildProtocol(self, clientAddress):
if clientAddress.host == '1.3.3.7':
# Reject it
return None
# Accept everything else
return WrappingFactory.buildProtocol(self, clientAddress)
def unregisterProtocol(self, p):
print "Unregister called"
삭제하려는 리소스는 무엇입니까? 그것은 ConsoleMessage()가 lambda에서 생성 된 것입니까? 쓰레기 수거가 아닌지 어떻게 확신합니까? ConsoleMessageDelivery에 대한 __del__ 메소드가 호출되지 않는다면, 실제 문제는 그 객체가 결코 가비지 수집되지 않는다는 것입니다. –
ConsoleMessageDelivery의 생성자에서 다른 것들과 함께 데이터베이스 연결을 여는 객체를 인스턴스화합니다. SMTP 연결이 닫히면 리소스 부족을 막기 위해 데이터베이스 연결도 닫아야합니다. 흥미롭게도 위의 DenyFactory 같은 랩핑 팩토리를 사용하지 않고 TimeoutFactory도 사용하면 __del __() 메서드가 예상대로 호출됩니다. 포장 공장에서 누수가 될 수 있습니까? –