Форум сайта python.su
Здравствуйте!
Имеется сервер на twisted, к которому возможен доступ по HTTP:
web = internet.TCPServer(PORT, server.Site(resource))
class AnyResource(resource.Resource): def render_GET(self, request): ... many_calculations() # долгие вычисления на CPU ... return NOT_DONE_YET
Офлайн
Да к тож знает, какие у вас там “many_calculations”. Но `multiprocessing` я бы не использовал (как и `os.fork`), он не в тему, и могут возникнуть трудноуловимые проблемы из-за того что, если закрытие левых файловых дескрипторов проблем не представляет, то “чистить структуры” после форка та ещё задачка. Можно конечно форкнуть (например с помощью `multiprocessing`) детей в самом начале работы процесса, когда он максимально чист, настроить с ними контакт через `stdio`, например, но это геморрой на мой взгляд, нужно ли оно вам.
Если ресурсоёмкая задача хорошо разбивается на мелкие части, посмотрите так же в сторону `twisted.internet.task.coiterate` (и `twisted.application.internet.CooperatorService` для понту). Тут конечно не очень хорошо ресурсы процессора будут утилизированы, но не будет блокировок и может для ваших нужд хватит. Вещь довольно простая и минимум побочных эффектов, а вот в случае с `ampoule` или `spawnProcess` придётся поднапрячься.
..bw
Офлайн
bwДва вида, 1) например:
Да к тож знает, какие у вас там “many_calculations”
for i in xrange(10**8): k += i
class AnyCommand(amp.Command): arguments = [("n", amp.Integer())] response = [("response", amp.String())] class AnyProtocol(child.AMPChild): @AnyCommand.responder def process(self, n): res = many_calculations(n) return {"response": resp}
for i in xrange(10**8): k += i
Отредактировано simplecode (Ноя. 6, 2013 12:02:35)
Офлайн
Разбираюсь с ampoule.
Исходники примера (файлы main.py и worker.py):
https://bitbucket.org/simple-code/test_ampoule/src/9e8e631b9723bb0a1e14b40e3ec3a20610b4ac0f/main.py?at=default
Вопрос все тот же:
Как вернуть из AnyProtocol.protocol то значение, которое возвращает функция many_calculations? Или же придется переписать many_calculations, чтобы она возвращала, что-то понятное методу AnyProtocol.protocol (str для примера выше)?
Офлайн
1) В `coiterate` можно запихнуть, если конечно в сам код можно внести изменения.
2) Может вообще в этой не имеет смысла использовать Twisted. Напишите “традиционный” скрипт и запускайте его через `spawnProcess`, общение с мастером через stdio. Какой-то сложный и большой результат должен возвращаться в мастер-процесс или что-то в стиле “хорошо”/“хреново”?
`amp.Integer`, `amp.String`, <напиши свой тип>. Если туда-сюда передаются сложные значения, всё равно придётся делать сериализацию, а куда она будет инкапсулирована, это вопрос вкусов/принципов/религии. В свой тип или куда-то ещё с использованием `amp.String` для приёма/передачи.
Код, в котором используется SQLAlchemy и обход дерева, требует ли Twisted? Думаю нет и использовать здесь `twisted.protocols.amp`, ampoule и Twisted вообще не целесообразно. Я бы запускал Свои скрипты, без движка Twisted через `spanProcess`, а ввод-вывод организовал через stdio. Если таких запусков много, то разумно не завершать процесс, а оставлять его ждать следующего обращения мастер-процесса. Так же можно создать пул таких дочерних работяг.
Опишите частоту обращения к (1) и (2) и формат/объём данных, которые передаются и возвращаются.
..bw
Офлайн