Pull to refresh

Django в неблокирующем стиле, или в погоне за Священным Граалем

Reading time 2 min
Views 4.6K
image

Присказка


При чтении о Twisted, Tornado, Node.js, у многих python-программистов возникает вопрос — «а вот если взять, и переписать Django в неблокирующем стиле?». Обычный ответ на этот вопрос — нет, не дождетесь. И правда, чтобы переписать целый фреймворк в макаронно-колбечном стиле, надо очень много сил, и большой заряд энтузиазма. Писать с колбеками, очень сомнительное удовольствие.

Так бы и было, но как я писал в своей прошлой заметке, есть в python-мире greenlet-ы, которые легким движением руки помогают скрыть от программиста все эти асинхронные моменты, до определенной степени. В момент написания той заметки, к мысли заставить работать Django в неблокирующем режиме, я относился весьма скептически — ну в самом деле, кто за это возьмется?



Суть


А на самом деле все не так страшно, следите за руками — мы создаем WSGI ресурс в Twisted, начинаем слушать HTTP-запросы; каждый запрос мы отдаем в WSGI-обработчик Django, оборачивая его в гринлет; любые запросы, которые можно преобразовать в неблокирующие, передаем Twisted, который пнет наш гринлет в момент готовности данных; готово!

image

А что же у нас есть такого, что можно обратить в неблокирующий режим в первую очередь? В Django основным таким местом выступает база данных. Можно ли с ней общаться асинхронно? Абсолютно верно, но нужен специальный драйвер.

С давних пор в Twisted есть такой — PGAsync. У него есть серьезные проблемы, он давно заброшен, но кто нам мешает подхватить упавшее знамя? Я сделал такую попытку, на данный момент драйвер работает стабильнее оригинала, но работа еще не закончена. Тем не менее, асинхронную БД для Django мы получить можем, и это будет Postgresql (ох, простите, пользователи Mysql, но кто вам мешает написать свой?). Драйвер используется в текущем проекте, разрабатываемом Imarto Networks imarto.net, и было решено выложить его для свободного использования. Я выложил его раньше готовности, только для демонстрации асинхронного Django, будьте снисходительны.

Чтобы использовать его в Django, нам надо написать свой БД-бэкенд. Я наворотил что-то из бэкенда для psycopg2, обернув обращения к драйверу БД в функции передачи управления главному гринлету, то есть основному потоку программы. Стандартный wsgi-ресурс из twisted.web пришлось тоже немного переделать, ведь он теперь должен кидать запросы на обработку не в пул потоков, а в гринлеты.

Как пощупать


Исходники можно получить тут, там же тестовый django-проект — bitbucket.org/deepwalker/tx_green
Исходники драйвера к БД — bitbucket.org/deepwalker/tx-postgresql

Для использования надо разместить pgasync, green_wsgi.py, tx_green.py, tx_postgresql в место, где интерпретатор сможет их найти. Затем в каталоге test_green_dj настраиваем параметры подключения к БД, ./manage.py syncdb, twistd -n — y server.py. Все, по адресу 127.0.0.1:8001 встречаем наш тестовый проект.

Про тесты


Тесты, которые я проводил, относились в основном к проверке работы, прироста производительности я не измерял. Если кто-то потратит свое время на это доброе дело, буду благодарен, если поделитесь результатами.
Tags:
Hubs:
+47
Comments 64
Comments Comments 64

Articles