coroutine in Python Tornado and NodeJs

简介:

yield and generator will be the front knowledge of this article. And you should also have some sense ofepoll/kqueue and callback style.
Let's enjoy the source code of the implement of coroutine.

Python Tornado

A simple async fetch function used by a coroutine in Python, exception handle removed

def fetch(self, request):
    future = TracebackFuture() # TracebackFuture == Future
    def handle_response(response):
        future.set_result(response)
    self.fetch_impl(request, handle_response) # This is a async function
    return future

def fetch_impl(self, request, callback):
    pass

future -- an instance of Future -- is an object that used to collect and send result to generator.

A coroutine that uses above fetch

@gen.coroutine
def request(self, uri):
    response = yield http.fetch(uri)

And we all know @gen.coroutine is a syntax sugar of

request = gen.coroutine(request)

coroutine wrapper function, also exception handle removed

def _make_coroutine_wrapper(func, replace_callback):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        future = TracebackFuture()
        try:
            result = func(*args, **kwargs) # result is a generator if the function is a generator function
        except (Return, StopIteration) as e:
            result = getattr(e, 'value', None)
        else:
            if isinstance(result, types.GeneratorType): # if the function is a generator function
                try:
                    yielded = next(result) # generator.next() will run the code above and right hand of the generator, for our example request here, http.fetch(uri) will run and return yielded(a instance of Future).
                except (StopIteration, Return) as e:
                    future.set_result(getattr(e, 'value', None))
                else:
                    Runner(gen=result, result_future=future, first_yielded=yielded) # Runner is like the co lib in Js written by TJ, Runner use a While True rather than recursive, because recursive is slower in Python.
                return future
            else: # or the function is jsut a normal function
              pass 
        future.set_result(result)
        return future
    return wrapper

With the Tornado usage we can learn that the function after yield can be either a coroutine or a normal function. 
Both of them returns a Future. You can write return Future by yourself or use @coroutine. But make sure your normal function is an async function.

Runner.run function, exception handle removed

def __init__(self, gen, result_future, first_yielded): # init of Runner
    ... # some attrs bind
    self.future = first_yielded # removed some complex logic, just show the basic logic of running the `request` generator.
    self.io_loop.add_future(
                self.future, lambda f: self.run()) # io_loop is a epoll based loop, the second function is a callback function when future is finished.

def run(self):
"""Starts or resumes the generator, running until it reaches a
yield point that is not ready.
"""
    while True:
        if not future.done():
            return
        try:
            value = future.result()
            yielded = self.gen.send(value)
        except (StopIteration, Return) as e:
            self.finished = True
            return
        except Exception:
            self.finished = True
            return
        if not self.handle_yield(yielded):
            return

Runner is like the co lib in Js written by TJ, Runner use a While True rather than recursive, because recursive is slower in Python. Both of them do the same thing, that is executing the generator unitl it's done.

First of all, Runner add the future, or we can say the async function fetch to io_loop. If fetch is finish, itself will invoke the callback function handle_response to set data to future. And the io_loop will invoke another callback function lambda f: self.run() to run the function run to get the result from future by value = future.result() andsend to the generator by yield = gen.send(value) and start the next block of the generator function if exists until the whole function is stoped and return a StopIteration.

So let us figure out the effect of each object:

  • generator function: a function with yield statement
  • generator: invoke a generator function will return a generator
  • coroutine: a wrapper function to wrapper a generator function. It will create a runner to run the generator.
  • Future: used to collect and get result, it's a result container.
  • Runner: it will register the future to io_loop and send result back to generator, and repeats unitl generator is done.

JavaScript

TODO


目录
相关文章
|
JavaScript 前端开发 Python
Node.js在Python中的应用实例demo
Node.js在Python中的应用实例demo
118 2
|
JavaScript 前端开发 API
Node.js在Python中的应用实例解析
Node.js在Python中的应用实例解析
|
7月前
|
缓存 自然语言处理 数据库
构建高效Python Web应用:异步编程与Tornado框架
【5月更文挑战第30天】在追求高性能Web应用开发的时代,异步编程已成为提升响应速度和处理并发请求的关键手段。本文将深入探讨Python世界中的异步编程技术,特别是Tornado框架如何利用非阻塞I/O和事件循环机制来优化Web服务的性能。我们将剖析Tornado的核心组件,并通过实例演示如何构建一个高效的Web服务。
|
3月前
|
数据处理 开发者 Python
浅析Python中的异步编程:从asyncio到Tornado
Python的异步编程是提升应用性能的关键。本文从Python的异步编程概念入手,探讨了asyncio库的使用及其在实际开发中的应用,并分析了Tornado框架的异步模型,以及如何将异步思维运用于实际项目中。
|
6月前
|
前端开发 JavaScript Python
Python之Tornado web 框架详解
Python之Tornado web 框架详解
47 0
|
7月前
|
网络协议 数据库 开发者
构建高效Python Web应用:异步编程与Tornado框架
【4月更文挑战第29天】在Web开发领域,响应时间和并发处理能力是衡量应用性能的关键指标。Python作为一种广泛使用的编程语言,其异步编程特性为创建高性能Web服务提供了可能。本文将深入探讨Python中的异步编程概念,并介绍Tornado框架如何利用这一机制来提升Web应用的性能。通过实例分析,我们将了解如何在实际应用中实现高效的请求处理和I/O操作,以及如何优化数据库查询,以支持更高的并发用户数和更快的响应时间。
|
7月前
|
物联网 调度 开发者
构建高效Python Web应用:异步编程与Tornado框架解析
【2月更文挑战第27天】 在处理高并发的Web应用场景时,传统的同步阻塞模型往往难以满足性能需求。本文将深入探讨Python世界中的异步编程概念,并结合Tornado这一轻量级、非阻塞式Web服务器及框架,展示如何构建高性能的Web应用。通过实例驱动的方法论,我们将剖析Tornado的核心组件,包括其IOLoop、异步HTTP客户端和服务器端处理机制,以及与协程集成的细节。文章旨在为开发者提供一套实践指南,帮助他们利用Python实现快速响应和资源高效的Web服务。
|
7月前
|
监控 调度 开发者
构建高效Python Web应用:异步编程与Tornado框架深度解析
【2月更文挑战第20天】在处理高并发的Web应用时,传统的同步阻塞模型往往难以满足性能要求。本文将深入探讨Python异步编程的原理及其优势,并通过Tornado框架的案例分析,展示如何构建一个高效的异步Web服务。我们将从异步IO的基础讲起,逐步过渡到Tornado的核心组件,最终实现一个能够承载大量并发连接的Web服务器,为追求高性能Web解决方案的开发者提供实践指南。
|
JavaScript 前端开发 中间件
python web 开发与 Node.js + Express 创建web服务器入门
python web 开发与 Node.js + Express 创建web服务器入门
186 0
|
Python
python问答社区BBS网络论坛社区平台系统源码Tornado
python问答社区BBS网络论坛社区平台系统源码Tornado
141 0