Small projects and libs
Python
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
tests
tx_postgresql
tx_tokyo
README.html
twsgi.py
tx_green.py
txdj_memcache.py

README.html

Как обычно, в праздники, в свободное время от затирки плитки и прочих прибиваний плинтуса, меня захватила очередная идея из цикла "попробовать". На хабре проскочила статья о <a href="http://habrahabr.ru/blogs/python/80062/">Pyrant</a>. Первой итерацией я взял и переделал основную часть протокола на Twisted - http://github.com/Deepwalker/tx-tokyo . И все было хорошо, наступление шло по всем фронтам, но тут я перешел к питоничной части pyrant, и понял что сделать yield a[megakey]='mega data string', вообще говоря невозможно. Это было очень печально, ведь в статье меня зацепило именно легкое обращение с данными в питоничной форме. Что же делать, Пух, спросил я себя? И вспомнил о <a href="http://codespeak.net/py/0.9.2/greenlet.html">greenlet-ах</a>.

<habracut />

Помучавшись некоторое время, я переписал defer.inlineCallbacks на использование greenlet-ов и смог написать такой код:
<code><pre>
from twisted.internet import defer, protocol, reactor
from tx_green import inlineCallbacks
from greentokyo import Tyrant

@inlineCallbacks
def test_proto():
    t = Tyrant() 
    print t.get_stats()

    t['kuku'] = 'Green Tyrant!'
    print t['kuku']

    reactor.stop()

if __name__=='__main__':
    test_proto()
    reactor.run()
</pre></code>

Удобство в том, что greenlet-ы имеют важное отличие от генераторов - они не ограничены одной функцией. То есть при вызове t['kuku'], на самом деле вызывается t.__getitem__, внутри которого мы и делаем вызов switch() для возврата управления основному циклу на время, пока мы ожидаем данные от сервера. Если бы мы попробовали сделать внутри t.__getitem__ yield, то мы бы просто сделали из него генератор, не получив никакой пользы.

Неудобство состоит в том, что надо помнить обо всей этой начинке - будет плохо если вы будете ждать данные, а вместо этого вам упадет просто Deferred. И будет еще хуже, если вы забудете вернуть управление основному потоку - остановите все приложение. И еще в этом варианте не светит "not twist your brain", потому что надо помнить и использовать возможности Twisted.

Реализация расположена моей <a href="http://github.com/Deepwalker/deepwalker_sandbox">песочнице</a>.

Вот такой небольшой пост. Как всегда ожидаю приятного обсуждения, и надеюсь, что будут хорошие предложения по коду, как было в прошлой нашей встрече, со мной в амплуа постописателя.