【发布时间】:2016-05-31 14:12:28
【问题描述】:
我正在使用 twisted 连接到套接字服务器,并且我正在使用 django 命令运行 twisted:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
from twisted.internet import reactor, task
from twisted.internet.protocol import ReconnectingClientFactory
from twisted.protocols.basic import LineReceiver
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
class SocketClientProtocol(LineReceiver):
MAX_LENGTH = 64*1024*1024
def __init__(self):
self.setLineMode()
def connectionMade(self):
print "CONNECTION ESTABLISHED"
def connectionLost(self, reason):
print "CONNECTION LOST"
print reason.getErrorMessage()
def lengthLimitExceeded(self, length):
print "EXCEED"
print length
def lineReceived(self, msg):
data = json.loads(msg)
#do sth with the data from the socket server
handle_message(data["type"], data["data"])
class SocketClientFactory(ReconnectingClientFactory):
def startedConnecting(self, connector):
print 'Started to connect.'
def buildProtocol(self, addr):
print 'Connected'
self.resetDelay()
return SocketClientProtocol()
def clientConnectionLost(self, connector, reason):
print 'Lost connection. Reason:', reason
ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
def clientConnectionFailed(self, connector, reason):
print 'Connection failed. Reason:', reason
ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
class Command(BaseCommand):
def handle(self, *args, **options):
client_factory = SocketClientFactory()
reactor.connectUNIX(settings.UNIX_OUT_SOCKET, client_factory)
reactor.run()
我通过python manage.py connect 启动这个命令,然后让进程在Apache 后面的一个wsgi 网络服务器旁边运行。这很好用,但我遇到的问题是,在此套接字客户端中启动的数据库连接通常不会正确关闭,而只是作为打开和空闲连接堆积起来。
select * from pg_stat_activity where datname = 'lt';的输出:
datid | datname | pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | xact_start | query_start | state_change | waiting | state | query
36649 | lt | 11026 | 16384 | dbuser | | 127.0.0.1 | | 55167 | 2016-05-31 15:50:38.417288+02 | | 2016-05-31 15:50:38.450209+02 | 2016-05-31 15:50:38.451045+02 | f | idle | SELECT "mediatorapp_audiostream"."id", "mediatorapp_audiostream"."language_tag", "mediatorapp_audiostream"."session_id", "mediatorapp_audiostream"."out_file", "mediatorapp_audiostream"."source_file" FROM "mediatorapp_audiostream" WHERE "mediatorapp_audiostream"."id" = '1104880479774183399:de'
36649 | lt | 11132 | 16384 | dbuser | | 127.0.0.1 | | 55348 | 2016-05-31 15:50:48.057967+02 | | 2016-05-31 15:50:48.089656+02 | 2016-05-31 15:50:48.090441+02 | f | idle | SELECT "mediatorapp_audiostream"."id", "mediatorapp_audiostream"."language_tag", "mediatorapp_audiostream"."session_id", "mediatorapp_audiostream"."out_file", "mediatorapp_audiostream"."source_file" FROM "mediatorapp_audiostream" WHERE "mediatorapp_audiostream"."id" = '1104880479774183399:de'
36649 | lt | 10386 | 16384 | dbuser | | 127.0.0.1 | | 53816 | 2016-05-31 15:49:19.597695+02 | | 2016-05-31 15:49:19.633149+02 | 2016-05-31 15:49:19.634685+02 | f | idle | SELECT "mediatorapp_audiostream"."id", "mediatorapp_audiostream"."language_tag", "mediatorapp_audiostream"."session_id", "mediatorapp_audiostream"."out_file", "mediatorapp_audiostream"."source_file" FROM "mediatorapp_audiostream" WHERE "mediatorapp_audiostream"."id" = '1104880479774183399:de'
36649 | lt | 11145 | 16384 | dbuser | | 127.0.0.1 | | 55356 | 2016-05-31 15:50:48.353581+02 | | 2016-05-31 15:50:48.389896+02 | 2016-05-31 15:50:48.390985+02 | f | idle | SELECT "mediatorapp_audiostream"."id", "mediatorapp_audiostream"."language_tag", "mediatorapp_audiostream"."session_id", "mediatorapp_audiostream"."out_file", "mediatorapp_audiostream"."source_file" FROM "mediatorapp_audiostream" WHERE "mediatorapp_audiostream"."id" = '1104880479774183399:de'
36649 | lt | 11150 | 16384 | dbuser | | 127.0.0.1 | | 55373 | 2016-05-31 15:50:49.705282+02 | | 2016-05-31 15:50:49.7269+02 | 2016-05-31 15:50:49.729029+02 | f | idle | SELECT "mediatorapp_audiodata"."id", "mediatorapp_audiodata"."index", "mediatorapp_audiodata"."source_file", "mediatorapp_audiodata"."duration", "mediatorapp_audiodata"."audiostream_id", "mediatorapp_audiodata"."start_timestamp", "mediatorapp_audiodata"."stop_timestamp" FROM "mediatorapp_audiodata" WHERE "mediatorapp_audiodata"."id" = 419871
36649 | lt | 10944 | 16384 | dbuser | | 127.0.0.1 | | 54990 | 2016-05-31 15:50:27.940832+02 | | 2016-05-31 15:50:27.978202+02 | 2016-05-31 15:50:27.97917+02 | f | idle | SELECT "mediatorapp_audiostream"."id", "mediatorapp_audiostream"."language_tag", "mediatorapp_audiostream"."session_id", "mediatorapp_audiostream"."out_file", "mediatorapp_audiostream"."source_file" FROM "mediatorapp_audiostream" WHERE "mediatorapp_audiostream"."id" = '1104880479774183399:de'
36649 | lt | 11059 | 16384 | dbuser | | 127.0.0.1 | | 55243 | 2016-05-31 15:50:42.737117+02 | | 2016-05-31 15:50:42.773878+02 | 2016-05-31 15:50:42.774562+02 | f | idle | SELECT "mediatorapp_audiostream"."id", "mediatorapp_audiostream"."language_tag", "mediatorapp_audiostream"."session_id", "mediatorapp_audiostream"."out_file", "mediatorapp_audiostream"."source_file" FROM "mediatorapp_audiostream" WHERE "mediatorapp_audiostream"."id" = '1104880479774183399:de'
36649 | lt | 11127 | 16384 | dbuser | | 127.0.0.1 | | 55342 | 2016-05-31 15:50:47.868249+02 | | 2016-05-31 15:50:47.905184+02 | 2016-05-31 15:50:47.90642+02 | f | idle | SELECT "mediatorapp_audiostream"."id", "mediatorapp_audiostream"."language_tag", "mediatorapp_audiostream"."session_id", "mediatorapp_audiostream"."out_file", "mediatorapp_audiostream"."source_file" FROM "mediatorapp_audiostream" WHERE "mediatorapp_audiostream"."id" = '1104880479774183399:de'
36649 | lt | 10901 | 16384 | dbuser | | 127.0.0.1 | | 54896 | 2016-05-31 15:50:23.208558+02 | | 2016-05-31 15:50:23.246194+02 | 2016-05-31 15:50:23.247041+02 | f | idle | SELECT "mediatorapp_audiostream"."id", "mediatorapp_audiostream"."language_tag", "mediatorapp_audiostream"."session_id", "mediatorapp_audiostream"."out_file", "mediatorapp_audiostream"."source_file" FROM "mediatorapp_audiostream" WHERE "mediatorapp_audiostream"."id" = '1104880479774183399:de'
在某些时候,这会导致以下错误:
OperationalError: FATAL: remaining connection slots are reserved for non-replication superuser connections
上面列出的查询是由这个函数生成的:
def get_audio_stream(audiostream_id):
try:
return AudioStream.objects.get(id=audiostream_id)
except AudioStream.DoesNotExist:
return None
所以我只是想通过它的 id 来获取一个对象。据我所知,Django 应该在之后关闭连接,但事实并非如此。 Is 不是唯一不时挂起的查询,其他查询也是如此。但这是最常见的一个。
我正在使用最新的 django (9.6)、twisted 15.5 和 Postgresql 9.3。我已经尝试将 CONN_MAX_AGE 设置为不同的值,但没有成功。
那么这个问题的原因是什么?是因为我在这个扭曲的引擎后面运行它吗?我该如何解决?
【问题讨论】:
标签: python django postgresql twisted