Landscaping Twisted

    As usual, on holidays, in my spare time from grouting tiles and other nailing of the skirting board, I was captured by the next idea from the “try” cycle. Habre has slipped article about Pyrant . The first iteration I took and redid the main part of the protocol on Twisted - github.com/Deepwalker/tx-tokyo . And everything was fine, the attack went on all fronts, but then I moved on to the pythonic part of pyrant, and realized what to do yield a [megakey] = 'mega data string', generally speaking it is impossible. It was very sad, because in the article I was hooked on the easy handling of data in a pythonic form. What to do, Pooh, I asked myself? And remembered the greenlet-ah .



    After a while, I rewrote defer.inlineCallbacks to use greenlets and was able to write this code:
    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()
    


    Convenience is that greenlets have an important difference from generators - they are not limited to one function. That is, when t ['kuku'] is called, t .__ getitem__ is actually called, inside which we make switch () to return control to the main loop for a while, while we are waiting for data from the server. If we tried to make get .emit__ yield inside t .__, then we would just make a generator out of it without getting any benefit.

    As you can see, it’s enough to wrap one function, and everything inside it will start to work in non-blocking mode. Moreover, if some modules will use already modified versions of the underlying modules, their syntax will not change. That is completely. Example - I will add my fork pyrant to twisted using greenlets, and I can use models without changes.

    The inconvenience is that you need to remember about all this stuffing - it will be bad if you wait for the data, but instead just Deferred will fall. And it will be even worse if you forget to return control to the main thread - stop the entire application. And in this option, “not twist your brain” does not shine, because you need to remember and use the capabilities of Twisted.

    It is worth noting that in the above code there is nothing explicitly indicating a return of control - calls to greenlet.switch () are hidden in the implementation of the python Tyrant. That is, it is imprisoned for this implementation. If this were not so, then we would have to explicitly call the wait function from tx_green. It is this moment that bothers me - you can create almost a jungle, and accessing the database through ORM will also secretly cause wait, but if you forget it, you can potentially generate an elusive error, or a novice, as usual without reading the documentation properly, will start asking page server through urllib and it will be a long time wondering why the server slows down.

    The implementation is located in my sandbox .

    Here is such a small post. As always, I expect a pleasant discussion, and I hope that there will be good suggestions for the code, as in our last meeting, with me in the role of a writer. Thanks for attention.

    Also popular now: