Я использую Redis для отслеживания всех подключенных клиентов / устройств. Сервер сокетов написан с использованием Twisted. Поскольку состояние redis должно быть инициализировано перед запуском сокет-сервера, и синхронизировано после получения сигнала TERM от ОС. Я хотел бы реализовать два заводских метода.
Я попытался реализовать код следующим образом. но не удалось.
import txredisapi as redis
from twisted.internet import defer
conf = EpicConf().loadConf()
dbid = string.atoi(conf['Redisdbid'])
rcs = redis.lazyConnection(password=conf['RedisPassword'], dbid=dbid, reconnect=True)
dbpool = adbapi.ConnectionPool("MySQLdb",db=conf['DbName'],user=conf['DbAccount'],\
passwd=conf['DbPassword'],host=conf['DbHost'],\
use_unicode=True,charset=conf['DbCharset'],cp_reconnect=True)
class PlainTCP(protocol.Protocol, TimeoutMixin):
global conf
def __init__(self, factory):
self.factory = factory
class PlainTCPFactory(protocol.Factory):
global conf
onlineDevices = 'GlinkOnlineDevices'
timezone = 8 # for CST +8
def __init__(self):
global conf
print "Info: Version={}, TimeOutIdle={}".format(__version__, conf['TimeOutIdle'])
def buildProtocol(self, addr):
return PlainTCP(self)
#@defer.inlineCallbacks
def startFactory(self):
#global rcs
print "beforeRunning(): clean redis for running"
#yield rcs.delete(self.onlineDevices)
#@defer.inlineCallbacks
def stopFactory(self):
#global rcs
print "afterRunning(): load from redis for logging"
#yield rcs.delete(self.onlineDevices)
def main():
#or another init redis operations here
reactor.listenTCP(6000, PlainTCPFactory(), interface="0.0.0.0")
reactor.run
#or another sync redis operations here
if __name__ == "__main__":
main()
Из фрагмента кода видно, что я пытался добавить код двумя фабричными методами:
- startFactory ()
- stopFactory ()
Но @ defer.inlinecallbacks и yield будут выдавать ошибки следующим образом, если я раскомментирую startFactory ():
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/Twisted-15.0.0-py2.7-linux-i686.egg/twisted/internet/defer.py", line 1107, in _inlineCallbacks
result = g.send(result)
File "EpicGlinkTcpServer.py", line 887, in startFactory
yield rcs.delete(self.onlineDevices)
File "/usr/local/lib/python2.7/dist-packages/txredisapi-1.2-py2.7.egg/txredisapi.py", line 1698, in wrapper
d = self._factory.getConnection()
File "/usr/local/lib/python2.7/dist-packages/Twisted-15.0.0-py2.7-linux-i686.egg/twisted/internet/defer.py", line 1253, in unwindGenerator
return _inlineCallbacks(None, gen, Deferred())
--- <exception caught here> ---
File "/usr/local/lib/python2.7/dist-packages/Twisted-15.0.0-py2.7-linux-i686.egg/twisted/internet/defer.py", line 1107, in _inlineCallbacks
result = g.send(result)
File "/usr/local/lib/python2.7/dist-packages/txredisapi-1.2-py2.7.egg/txredisapi.py", line 2037, in getConnection
raise ConnectionError("Not connected")
txredisapi.ConnectionError: Not connected
И выбросить следующие ошибки, если я раскомментирую stopFactory ().
2018-09-02 16:11:24+0800 [BaseRedisProtocol,client] <twisted.internet.tcp.Connector instance at 0x9951e2c> will retry in 2 seconds
2018-09-02 16:11:24+0800 [BaseRedisProtocol,client] Stopping factory <txredisapi.RedisFactory instance at 0x9951dac>
2018-09-02 16:11:24+0800 [__main__.PlainTCPFactory] (TCP Port 6000 Closed)
2018-09-02 16:11:24+0800 [__main__.PlainTCPFactory] Stopping factory <__main__.PlainTCPFactory instance at 0x9962aac>
2018-09-02 16:11:24+0800 [__main__.PlainTCPFactory] afterRunning(): load from redis for logging
2018-09-02 16:11:24+0800 [__main__.PlainTCPFactory] Unhandled error in Deferred:
2018-09-02 16:11:24+0800 [__main__.PlainTCPFactory] Unhandled Error
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/Twisted-15.0.0-py2.7-linux-i686.egg/twisted/internet/defer.py", line 1107, in _inlineCallbacks
result = g.send(result)
File "EpicGlinkTcpServer.py", line 893, in stopFactory
yield rcs.delete(self.onlineDevices)
File "/usr/local/lib/python2.7/dist-packages/txredisapi-1.2-py2.7.egg/txredisapi.py", line 1698, in wrapper
d = self._factory.getConnection()
File "/usr/local/lib/python2.7/dist-packages/Twisted-15.0.0-py2.7-linux-i686.egg/twisted/internet/defer.py", line 1253, in unwindGenerator
return _inlineCallbacks(None, gen, Deferred())
--- <exception caught here> ---
File "/usr/local/lib/python2.7/dist-packages/Twisted-15.0.0-py2.7-linux-i686.egg/twisted/internet/defer.py", line 1107, in _inlineCallbacks
result = g.send(result)
File "/usr/local/lib/python2.7/dist-packages/txredisapi-1.2-py2.7.egg/txredisapi.py", line 2037, in getConnection
raise ConnectionError("Not connected")
txredisapi.ConnectionError: Not connected
Я понятия не имею, как реализовать правильный код здесь. У меня есть еще два варианта.
- Добавить еще одну библиотеку synchrouns redis, независимо от текущего txredisapi, добавить два кода в main ().
- Добавление сценариев в сценарий внешней оболочки bash.
Однако, если кто-то может помочь мне реализовать фабричные методы. это будет прекрасно.
Заранее спасибо.