Giter Site home page Giter Site logo

greenado's Introduction

greenado

Test status

Test coverage status

Documentation

Greenado is a utility library that provides greenlet-based coroutines for tornado. In tornado, coroutines allow you to perform asynchronous operations without using callbacks, providing a pseudo-synchronous flow in your functions.

When using Tornado's @gen.coroutine <tornado.gen.coroutine> in a large codebase, you will notice that they tend to be 'infectious' from the bottom up. In other words, for them to be truly useful, callers of the coroutine should 'yield' to them, which requires them to be a coroutine. In turn, their callers need to 'yield', and so on.

Instead, greenado coroutines infect from the top down, and only requires the @greenado.groutine <greenado.concurrent.groutine> decorator somewhere in the call hierarchy, but it doesn't really matter where. Once the decorator is used, you can use greenado.gyield() <greenado.concurrent.gyield> to pseudo-synchronously wait for asynchronous events to occur. This reduces complexity in large codebases, as you only need to use the decorator at the very top of your call trees, and nowhere else.

Documentation

Documentation can be found at http://greenado.readthedocs.org/en/latest/

Installation & Requirements

Installation is easiest using pip:

$ pip install greenado 

greenado should work using tornado 3.2, but I only actively use it in tornado 4+

I have only tested greenado on Linux & OSX, but I imagine that it would work correctly on platforms that tornado and greenlet support.

Example usage

In the below examples, 'main_function' is your toplevel function in the call hierarchy that needs to call things that eventually call some asynchronous operation in tornado.

Normal tornado coroutine usage might look something like this:

from tornado import gen

@gen.coroutine
def do_long_operation():
    retval = yield long_operation()
    raise gen.Return(retval)

@gen.coroutine
def call_long_operation():
    retval = yield do_long_operation()
    raise gen.Return(retval)

@gen.coroutine
def main_function():
    retval = yield call_long_operation()

With greenado, it looks something like this instead:

import greenado

def do_long_operation():
    retval = greenado.gyield(long_operation())
    return retval

def call_long_operation():
    retval = do_long_operation()
    return retval

@greenado.groutine
def main_function():
    retval = call_long_operation()

Functions wrapped by @greenado.groutine <greenado.concurrent.groutine> return a tornado.concurrent.Future object which you must either yield, call result(), or use IOLoop.add_future <tornado.ioloop.IOLoop.add_future> on, otherwise you may risk swallowing exceptions.

Why can't I use the yield keyword?

Well, actually, if you use yet another decorator, you still can! Check out this example:

import greenado

@greenado.generator
def do_long_operation():
    retval = yield long_operation()
    return retval

def call_long_operation():
    retval = do_long_operation()
    return retval

@greenado.groutine
def main_function():
    retval = call_long_operation()

You'll note that this is very similar to the coroutines available from tornado (and in fact, the implementation is mostly the same), but the difference is that (once again) you don't need to do anything special to call the do_long_operation function, other than make sure that @greenado.groutine <greenado.concurrent.groutine> is in the call stack somewhere.

Testing

greenado.testing contains a function called gen_test which can be used exactly like tornado.testing.gen_test:

import greenado

from greenado.testing import gen_test
from tornado.testing import AsyncTestCase

def something_that_yields():
    greenado.gyield(something())

class MyTest(AsyncTestCase):
    @gen_test
    def test_something(self):
        something_that_yields()

Contributing new changes

  1. Fork this repository
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Test your changes (tests/run_tests.sh)
  4. Commit your changes (git commit -am 'Add some feature')
  5. Push to the branch (git push origin my-new-feature)
  6. Create new Pull Request

Credit

Greenado is similar to and inspired by https://github.com/mopub/greenlet-tornado and https://github.com/Gawen/tornalet, but does not require that you use it from a tornado web handler as they do.

Authors

Dustin Spicuzza ([email protected])

greenado's People

Contributors

pfultz2 avatar virtuald avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

greenado's Issues

TimeoutError

It seems sometimes I'm getting a greenado.concurrent.TimeoutError from a gyield... but other times a tornado.gen.TimeoutError.

Any chance greenado TimeoutError could just inherit from tornado TimeoutError?

tornado.concurrent.TracebackFuture removed in Tornado 5.0

The TracebackFuture class was removed in Tornado 5.0, having been deprecated in a prior version. This is causing greenado to fail thusly:

Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/tornado/tcpserver.py", line 295, in _handle_connection
future = self.handle_stream(stream, address)
File "/usr/local/lib/python2.7/dist-packages/greenado/concurrent.py", line 186, in wrapper
future = concurrent.TracebackFuture()
AttributeError: 'module' object has no attribute 'TracebackFuture'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.