Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 服务器重新启动时多处理BaseManager的意外行为_Python 3.x - Fatal编程技术网

Python 3.x 服务器重新启动时多处理BaseManager的意外行为

Python 3.x 服务器重新启动时多处理BaseManager的意外行为,python-3.x,Python 3.x,我正在构建一个由几个独立进程组成的应用程序,其中每个进程都是一个python程序。它们都由supervisord实用程序启动,并在运行Ubuntu18.04下的Python3.8.0的venv中执行 其思想是进程通过队列进行通信,因此问题是如何将队列发送到进程。我的解决方案是使用多处理管理器来实现队列存储库。每个进程按名称请求队列 由于整个应用程序需要健壮,因此如果队列服务器进程停止并重新启动(由supervisord自动启动),它必须能够继续 我遇到的问题是,重新启动队列服务器后对connec

我正在构建一个由几个独立进程组成的应用程序,其中每个进程都是一个python程序。它们都由supervisord实用程序启动,并在运行Ubuntu18.04下的Python3.8.0的venv中执行

其思想是进程通过队列进行通信,因此问题是如何将队列发送到进程。我的解决方案是使用多处理管理器来实现队列存储库。每个进程按名称请求队列

由于整个应用程序需要健壮,因此如果队列服务器进程停止并重新启动(由supervisord自动启动),它必须能够继续

我遇到的问题是,重新启动队列服务器后对
connect()
的第一次调用不会返回队列

下面的顺序显示了一些手动测试。(我的测试环境在Windows 8.1上托管的virtualbox中运行Ubuntu)

在这里,我在另一个终端中启动了服务器,然后启动python,如下所示

这与第一次调用get_queue返回队列时的预期效果一样

(hydra_env) john@u1804-VirtualBox:~/sw/code/hydra$ python
Python 3.8.5 (default, Aug 13 2020, 15:42:06) 
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from multiprocessing.managers import BaseManager
>>> class QueueManager(BaseManager): pass
... 
>>> QueueManager.register('get_queue')
>>> mgr = QueueManager(address=('localhost', 50000), authkey=b'abracadabra' )
>>> mgr.connect()
>>> q = mgr.get_queue('name', 'src'); print(str(q))
<multiprocessing.queues.Queue object at 0x7f98403c1820>
>>> q = mgr.get_queue('name', 'src'); print(str(q))
<multiprocessing.queues.Queue object at 0x7f98403c1820>
>>> mgr.connect()
>>> q = mgr.get_queue('name', 'src'); print(str(q))
<AutoProxy[get_queue] object, typeid 'get_queue' at 0x7f280afdc160; '__str__()' failed>
>>> q = mgr.get_queue('name', 'src'); print(str(q))
<multiprocessing.queues.Queue object at 0x7ff5f1b46820>
^C(hydra_env) john@u1804-VirtualBox:~/sw/code/hydra$ python ../../trials/test_mgr.py 
starting
serving <multiprocessing.queues.Queue object at 0x7f98403c1820>
serving <multiprocessing.queues.Queue object at 0x7f98403c1820>
^C(hydra_env) john@u1804-VirtualBox:~/sw/code/hydra$ python ../../trials/test_mgr.py 
starting
serving <multiprocessing.queues.Queue object at 0x7ff5f1b46820>
serving <multiprocessing.queues.Queue object at 0x7ff5f1b46820>
>>> mgr = QueueManager(address=('localhost', 50000), authkey=b'abracadabra' )
>>> mgr.connect()
>>> q = mgr.get_queue('name', 'src'); print(str(q))
<AutoProxy[get_queue] object, typeid 'get_queue' at 0x7f280afdc2b0; '__str__()' failed>
>>> q = mgr.get_queue('name', 'src'); print(str(q))
<multiprocessing.queues.Queue object at 0x7ff8dabd7820>
>>>
from multiprocessing.managers import BaseManager
from multiprocessing import Queue

class QueueManager(BaseManager):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__queues = {} # dict of instances keyed on qname

    def get_queue(self, qname: str, src: str) -> Queue:
        if qname not in self.__queues:
            self.__queues[qname] = Queue()
        the_q = self.__queues[qname]
        print(f'serving {the_q}')
        return the_q


def main() -> None:
    """main for a process serving queues forever"""
    mgr = QueueManager(address=('localhost', 50000), authkey=b'abracadabra' )
    QueueManager.register('get_queue', callable=mgr.get_queue)
    server_object = mgr.get_server()
    print('starting')
    server_object.serve_forever()


if __name__ == '__main__':
    main()