Мне необходимо организовать взаимодействие между несколькоими компьютерами (фактически набор виртуальных машин, работающих на одной железной) по принципу: мастер + несколько слэйвов. Мастер поднимает слэйвы по необходимости, управляет снэпшотами виртуалки, раздает задачи, мониторит сетевые шары да и вообще много чего делает.
В принципе, к вопросу взаимодействия можно подойти довольно топорно: поднять на мастере HTTP сервер (на том же Twisted, думаю что без него или чего-то подобного все равно не обойтись) и разбирать запросы/отдавать команды через него. Этот вариант всем хорош, кроме необходимости сделать довольно большое количество кода вручную.
Что не хочется делать вручную:
— придумывать протокол взаимодействия;
— заниматься серриализацией/десерриализацией данных;
— организовывать обработку ошибок когда что-то в очередной раз, по-мелочи, отвалится;
— придумывать как информировать слэйва о том, где искать мастера.
Так вот, уважаемые знатоки Python, не подскажите ли мне библиотечки, которые позволят мне минимизировать ручную работу? В идеале, в библиотеке должно быть все начиная с транспорта, заканчивая серриализацией, ну или по частям набрать то, что мне нужно. Вообще, тут бы что-то типа AKKA вполне подошла, но распределенной версии нету, а со Scala я связываться мягко говоря не хочу.
Здравствуйте, kaa.python, Вы писали:
KP>- придумывать протокол взаимодействия; KP>- заниматься серриализацией/десерриализацией данных; KP>- организовывать обработку ошибок когда что-то в очередной раз, по-мелочи, отвалится;
Под это хорошо zerorpc подойдет
... << RSDN@Home 1.2.0 alpha 5 rev. 1511>>
"Бог не терпит голой сингулярности" -- Роджер Пенроуз
Здравствуйте, kaa.python, Вы писали:
KP>Так вот, уважаемые знатоки Python, не подскажите ли мне библиотечки, которые позволят мне минимизировать ручную работу? В идеале, в библиотеке должно быть все начиная с транспорта, заканчивая серриализацией, ну или по частям набрать то, что мне нужно. Вообще, тут бы что-то типа AKKA вполне подошла, но распределенной версии нету, а со Scala я связываться мягко говоря не хочу.
Здравствуйте, kaa.python, Вы писали:
KP>Здравствуйте, neFormal, Вы писали:
F>>свяжись с erlang'ом
KP>А как у него с интеграцией API виртуальных машин? Боюсь что таким образом избегая небольшой сложности я создам себе кучу проблем.
Здравствуйте, kaa.python, Вы писали:
KP>Так вот, уважаемые знатоки Python, не подскажите ли мне библиотечки, которые позволят мне минимизировать ручную работу? В идеале, в библиотеке должно быть все начиная с транспорта, заканчивая серриализацией, ну или по частям набрать то, что мне нужно.
А вот нету. Я в итоге писал свой сетевой слой и серилизацию в JSON.
Zeromq пробовал, но в чём от него толк — так и не понял.
Здравствуйте, kaa.python, Вы писали:
KP>Мне необходимо организовать взаимодействие между несколькоими компьютерами (фактически набор виртуальных машин, работающих на одной железной) по принципу: мастер + несколько слэйвов. Мастер поднимает слэйвы по необходимости, управляет снэпшотами виртуалки, раздает задачи, мониторит сетевые шары да и вообще много чего делает.
Здравствуйте, Cyberax, Вы писали:
C>А вот нету. Я в итоге писал свой сетевой слой и серилизацию в JSON.
Похоже что да Смотрю все эти ZeroMQ, RabbitMQ и создается ощущение что что-то перемудрили. Пока что что первоначальный вариант с Twisted + XML/JSON серриализацией выглядит лучшим вариантом
Здравствуйте, kaa.python, Вы писали:
C>>А вот нету. Я в итоге писал свой сетевой слой и серилизацию в JSON. KP>Похоже что да Смотрю все эти ZeroMQ, RabbitMQ и создается ощущение что что-то перемудрили. Пока что что первоначальный вариант с Twisted + XML/JSON серриализацией выглядит лучшим вариантом
Twisted не бери, он кака. Гораздо лучше взять gevent и что-нибудь типа Werkzeug или Flask. Получается намного приятнее.
Здравствуйте, Cyberax, Вы писали:
C>Twisted не бери, он кака. Гораздо лучше взять gevent и что-нибудь типа Werkzeug или Flask. Получается намного приятнее.
Да я с ним работал, вроде все прилично очень. А чем он кака? Можно немного деталей?
Здравствуйте, kaa.python, Вы писали:
C>>Twisted не бери, он кака. Гораздо лучше взять gevent и что-нибудь типа Werkzeug или Flask. Получается намного приятнее. KP>Да я с ним работал, вроде все прилично очень. А чем он кака? Можно немного деталей?
У меня было несколько проблем:
1) Сложные протоколы получаются очень большими из-за необходимости явно делать кучу состояний.
2) Потоковый вывод делать крайне неудобно, по той же причине.
3) У меня нормально не получилось прикрутить Subprocess-модуль.
Здравствуйте, Cyberax, Вы писали:
C>1) Сложные протоколы получаются очень большими из-за необходимости явно делать кучу состояний. C>2) Потоковый вывод делать крайне неудобно, по той же причине.
Вот эти две проблемы решаются довольно просто через State Machine. Да, тот самый SM из GoF.
C>3) У меня нормально не получилось прикрутить Subprocess-модуль.
Здравствуйте, kaa.python, Вы писали:
C>>1) Сложные протоколы получаются очень большими из-за необходимости явно делать кучу состояний. C>>2) Потоковый вывод делать крайне неудобно, по той же причине. KP>Вот эти две проблемы решаются довольно просто через State Machine. Да, тот самый SM из GoF.
Только через задницу. Получается кода примерно раз в 5 больше, чем с gevent'ом. Не говоря уж про то, что обычный линейный код читается в 100500 раз лучше, чем код КА.
C>>3) У меня нормально не получилось прикрутить Subprocess-модуль. KP>А вот это уже серьезно. Можно немного деталей?
Внутренний цикл Twisted не умеет работать с процессами, вот и всё. Добавить поддержку руками (через отлов SIGCHLD через signalfd) в теории можно, но я ниасилил.
Далее, у меня ещё была та проблема, что мне надо было создать слушающий сокет и форкнуть N штук процессов, которые accept'или бы соединения на этом сокете. Получилось только через большую задницу — используемый по умолчанию реактор с epoll не переживает fork()'а, а реактор с select() — тупой тормоз. Пришлось создавать сокет вручную, тщательно следя за тем, чтобы случайно не импортировать код Twisted (что вызывает старт реактора).
В итоге код на Gevent получился в несколько раз проще.
Здравствуйте, Cyberax, Вы писали:
C>Только через задницу. Получается кода примерно раз в 5 больше, чем с gevent'ом. Не говоря уж про то, что обычный линейный код читается в 100500 раз лучше, чем код КА.
Тут я с тобой совершенно не согласен. Оверхед довольно не велик и составляет около 10% + пара классов. Зато понятность в случае с запутанным протоколом получается +100 как минимум.
C>Внутренний цикл Twisted не умеет работать с процессами, вот и всё. Добавить поддержку руками (через отлов SIGCHLD через signalfd) в теории можно, но я ниасилил.
А что насчет spawnProcess из реактора? Как раз для этого штукенция запилена.
C>Далее, у меня ещё была та проблема, что мне надо было создать слушающий сокет и форкнуть N штук процессов, которые accept'или бы соединения на этом сокете. Получилось только через большую задницу — используемый по умолчанию реактор с epoll не переживает fork()'а, а реактор с select() — тупой тормоз. Пришлось создавать сокет вручную, тщательно следя за тем, чтобы случайно не импортировать код Twisted (что вызывает старт реактора).
Здравствуйте, kaa.python, Вы писали:
KP>Тут я с тобой совершенно не согласен. Оверхед довольно не велик и составляет около 10% + пара классов. Зато понятность в случае с запутанным протоколом получается +100 как минимум.
Как нормально сделать протокол, который переключает логического пользователя, делает авторизацию, и после этого разрешает вызов методов я так и не додумался. Получался жутик.
C>>Внутренний цикл Twisted не умеет работать с процессами, вот и всё. Добавить поддержку руками (через отлов SIGCHLD через signalfd) в теории можно, но я ниасилил. KP>А что насчет spawnProcess из реактора? Как раз для этого штукенция запилена.
А не работает. Можно сделать отдельный поток, который бы вызывал wait() на все запущенные процессы. Но потом у меня сломался select() на пайпах от процессов.
Здравствуйте, Cyberax, Вы писали:
C>Как нормально сделать протокол, который переключает логического пользователя, делает авторизацию, и после этого разрешает вызов методов я так и не додумался. Получался жутик.
Да вобщем-то довольно просто. Рисуешь граф вызовов с переходами между всеми состояниями, который и превращается в машину состояний практически без изменений. Зато нет проблем с раскиданными по коду "если флаг1 и флаг2 или не флаг3"...
C>А не работает. Можно сделать отдельный поток, который бы вызывал wait() на все запущенные процессы. Но потом у меня сломался select() на пайпах от процессов.
Здравствуйте, kaa.python, Вы писали:
KP>Да вобщем-то довольно просто. Рисуешь граф вызовов с переходами между всеми состояниями, который и превращается в машину состояний практически без изменений. Зато нет проблем с раскиданными по коду "если флаг1 и флаг2 или не флаг3"...
Ну вот очень простой код:
msg = read_message()
user, role = msg.split('\t')
if some_utility_module.check_authorization(db, user) == role:
self.assume_role(role)
...
Выливается в мегатонны говнокода на Twisted. Запрос к БД, например, надо руками выносить в пул потоков.
КА удобны, когда есть сложные переходы между состояниями. Но в большинстве протоколов всё тупо линейно.