Форум сайта python.su
15
Задача простая. Шлём на сервер get запрос с параметрами: имя xml-файла, и xpath-выражение, чтобы им раcпарсить xml. Xml-файл лежит в той же директории , что и сервер, для простоты. Сколько уже перечитал про асинхронность, так и не мог осознать абстракции tornado(что-то очевидно, что-то спрятано). Так же не могу выстроить в голове последовательность работы с версией сопрограмм(coroutines).
Допустим xml:
<?xml version="1.0" encoding="utf-8"?>
<main version="1">
<sub number="1">first</sub>
<sub number="2">second</sub>
</main>
from io import BytesIO from xml.etree import ElementTree as ET from tornado.ioloop import IOLoop from tornado.httpserver import HTTPServer from tornado.web import * from concurrent.futures import ProcessPoolExecutor class XpathHandler(RequestHandler): @asynchronous def get(self): #http://127.0.0.1:8888/xpath/?file=xml_file.orx&xpath=.// file_name = self.get_argument('file') xpath = self.get_argument('xpath') with ProcessPoolExecutor(max_workers=1) as executor: future = executor.submit(XpathHandler.parse_xml, file_name, xpath) future.add_done_callback(self.callback) @staticmethod def parse_xml(self, file_name, xpath): output = BytesIO() tree = ET.parse(file_name) root = tree.getroot() finded_elements = root.findall(xpath) resulted_element = ET.Element('result') resulted_element.extend(finded_elements) tree._setroot(resulted_element) tree.write(output, encoding='utf-8', xml_declaration=True) result = output.getvalue().decode() output.close() return result def callback(self, future): self.write(str(future.result())) self.finish() if __name__ == '__main__': application = Application([ (r"/xpath/", XpathHandler)], debug=True, ) http_server = HTTPServer(application) http_server.listen(8888, 'localhost') IOLoop.instance().start()
http://127.0.0.1:8888/xpath/?file=light_xml.xml&xpath=.//
Отредактировано buddha (Апрель 3, 2014 11:59:18)
Офлайн
32
А в чем конретно проблема?
Запрос в get приходит? Данные правильные (fiel_name…) ? Процесс запускается? Процесс возвращает результат? вызывает callback?
Если проблема с ProcessPoolExecutor, можете попробовать асинхронный запуск через subprocess приделать http://www.py-my.ru/post/501627e2bbddbd261e000000
Офлайн
32
concurrent.futures из стандартной либы, вроде он не как не связан с торнадо, и в теории должен блокировать торнадо при запуске.
Офлайн
15
o7412369815963
А в чем конретно проблема?Запрос в get приходит? Данные правильные (fiel_name…) ? Процесс запускается? Процесс возвращает результат? вызывает callback?Если проблема с ProcessPoolExecutor, можете попробовать асинхронный запуск через subprocess приделать http://www.py-my.ru/post/501627e2bbddbd261e000000
Traceback (most recent call last): File "C:\Python33\lib\multiprocessing\queues.py", line 245, in _feed send(obj) File "C:\Python33\lib\multiprocessing\connection.py", line 206, in send ForkingPickler(buf, pickle.HIGHEST_PROTOCOL).dump(obj) _pickle.PicklingError: Can't pickle <class 'function'>: attribute lookup builtins.function failed
o7412369815963Это не верно. Уже нырнул в исходный код, всё увидел, вот что документация говорит…
concurrent.futures из стандартной либы, вроде он не как не связан с торнадо, и в теории должен блокировать торнадо при запуске.
Futures are a pattern for concurrent programming introduced in Python 3.2 in the concurrent.futures package (this package has also been backported to older versions of Python and can be installed with pip install futures). Tornado will use concurrent.futures.Future if it is available; otherwise it will use a compatible class defined in this module.
Офлайн
32
buddhaПо идее там все просто, на пальцах так:
В целом проблема в том, что я не могу понять абстракций tornado для написания асинхронного кода.
buddhaок, я вот даже, якобы, рабочий пример нашел http://lbolla.info/blog/2013/01/22/blocking-tornado
Это не верно. Уже нырнул в исходный код, всё увидел, вот что документация говорит…
Офлайн
32
buddhaПробуйте ещё упрощать приложений до минимума пока не станет понятно что где и почему, при этом логируя на каждом углу.
В целом проблема в том, что я не могу понять абстракций tornado для написания асинхронного кода.
Офлайн
15
Как асинхронщика работает представление имею, писал примеры для клиента и сервера, основанные на select(). Вчера модель работы tornado смотрел тут http://www.slideshare.net/
За пример, спасибо. Но, как в нём и видно, он не соответствует tornado flow, по моему, хотя очень показательный!
Я то вот смотрел в код декораторов @asyncronous @gen.coroutine. Смотрел реализацию метода tornado.httpclient.AsyncHTTPClient.fetch(). Какой то блин колбэк колбэков.
Буду дальше страдать=( авось получиться разложить по полочкам. Хотя плохо это, когда дока не учит использовать внешнее API фреймворка.
Офлайн