правильно отключить многопроцессорный удаленный менеджер - PullRequest
3 голосов
/ 29 июня 2011

При использовании multiprocessing Диспетчер объектов для создания сервера и удаленного подключения к этому серверу клиент должен поддерживать соединение с удаленным сервером.Если сервер отключается до того, как клиент выключится, он всегда будет пытаться подключиться к ожидаемому адресу сервера.

Я захожу в тупик из-за клиентского кода, пытающегося выйти после того, как сервер ушел, поскольку мой клиентский процесс никогда не завершается.

Если я del удаленных объектов и моих клиентовДиспетчер до того, как сервер выйдет из строя, процесс завершится нормально, но удаление объекта диспетчера моего клиента и удаленных объектов сразу после использования не является идеальным.

Это лучшее, что я могу сделать?Есть ли другой (более правильный) способ отключиться от объекта удаленного менеджера?Есть ли способ чистого выхода из клиента после того, как сервер вышел из строя и / или соединение потеряно?

Я знаю, что socket.setdefaulttimeout не работает с многопроцессорной обработкой, но есть ли способ установить соединениетайм-аут для многопроцессорного модуля конкретно?Вот код, с которым у меня возникли проблемы:

from multiprocessing.managers import BaseManager
m = BaseManager(address=('my.remote.server.dns', 50000), authkey='mykey')
# this next line hangs forever if my server is not running or gets disconnected
m.connect()

ОБНОВЛЕНИЕ Это не работает в многопроцессорной среде.Тайм-аут соединения должен происходить на уровне сокета (и для этого сокет должен быть неблокирующим), но неблокирующие сокеты нарушают многопроцессорность.Невозможно справиться с отказом от установки соединения, если удаленный сервер недоступен.

Ответы [ 2 ]

1 голос
/ 30 марта 2012

есть ли способ установить тайм-аут соединения для многопроцессорного модуля конкретно?

Да, но это взлом.Я надеюсь, что кто-то с большим питон-фу сможет улучшить этот ответ.Тайм-аут для многопроцессорной обработки определен в multiprocessing/connection.py:

# A very generous timeout when it comes to local connections...
CONNECTION_TIMEOUT = 20.
...
def _init_timeout(timeout=CONNECTION_TIMEOUT):
        return time.time() + timeout

В частности, я смог заставить его работать, применив обезьянное исправление метода _init_timeout следующим образом:

import sys
import time

from multiprocessing import managers, connection

def _new_init_timeout():
    return time.time() + 5

sys.modules['multiprocessing'].__dict__['managers'].__dict__['connection']._init_timeout = _new_init_timeout
from multiprocessing.managers import BaseManager
m = BaseManager(address=('somehost', 50000), authkey='secret')
m.connect()

Где 5 - новое значение времени ожидания.Если есть более простой способ, я уверен, что кто-то укажет на это.Если нет, это может быть кандидатом на запрос функции в многопроцессорную команду разработчиков.Я думаю, что что-то столь же элементарное, как установка таймаута, должно быть проще, чем это.С другой стороны, у них могут быть философские причины не раскрывать тайм-аут в API.

Надеюсь, это поможет.

0 голосов
/ 29 августа 2011

Может ли это вам помочь?

#### TEST_JOIN_TIMEOUT

def join_timeout_func():
    print '\tchild sleeping'
    time.sleep(5.5)
    print '\n\tchild terminating'

def test_join_timeout():
    p = multiprocessing.Process(target=join_timeout_func)
    p.start()

    print 'waiting for process to finish'

    while 1:
        p.join(timeout=1)
        if not p.is_alive():
            break
        print '.',
        sys.stdout.flush()

(взято с Python 16.6 страницы)

Обычно тайм-ауты проверяются в некотором цикле while.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...