You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:确认Tornado异步程序正确性,实现请求异步监听

Fixing Your Async Tornado Application

Hey there! Let's get your Tornado app properly set up for async request handling. I noticed a few critical issues in your code that are keeping it from working as expected—let's break them down and fix them one by one:

Key Issues in Your Current Code

  • Incorrect Handler Parent Class: Your A and B classes inherit from tornado.web.Application, but request handlers should always inherit from tornado.web.RequestHandler instead. Application is the top-level app instance that routes requests to handlers, not the handler itself.
  • Missing Async Definitions for func/func2: You're using await on these functions, but they need to be defined as async functions (or wrapped to run asynchronously if they're blocking).
  • No Response Sent to Clients: Your handler methods don't send any response back, so clients will hang waiting for a reply.
  • Possible Import/Naming Typo: You imported fun and func2, but called func()—I'll assume that's a typo and adjust it to match your imports.

Corrected Async Tornado Code

Here's the fixed version with explanations:

import tornado.web
import tornado.ioloop
# Assume these are your async functions; adjust if they're blocking
import fun, func2

# Handlers inherit from RequestHandler, not Application
class A(tornado.web.RequestHandler):
    async def post(self):
        # Ensure func2 is an async function; if it's blocking, use run_in_executor
        result = await func2()
        # Send the result back to the client
        self.write({"result": result})
        # Finish the request (optional in Tornado, but explicit is good)
        self.finish()

class B(tornado.web.RequestHandler):
    async def put(self):
        # Fixed the typo to match your import (fun.func() instead of func())
        result = await fun.func()
        self.write({"result": result})
        self.finish()

def main():
    # Application instance registers routes to your handlers
    app = tornado.web.Application([
        (r"/A", A),
        (r"/B", B)
    ])
    return app

if __name__ == "__main__":
    app = main()
    app.listen(8000)
    # Start the async IOLoop
    tornado.ioloop.IOLoop.current().start()

Handling Blocking Functions (If func/func2 Are Sync)

If func or func2 are synchronous blocking functions (like CPU-heavy tasks or blocking I/O), you need to run them in a thread pool to avoid blocking the Tornado event loop. Here's how to adjust a handler for that:

async def put(self):
    # Use IOLoop's run_in_executor to run blocking functions asynchronously
    result = await tornado.ioloop.IOLoop.current().run_in_executor(
        None,  # Uses the default thread pool
        fun.func  # Pass the blocking function (without parentheses)
    )
    self.write({"result": result})

Verifying Async Behavior

To confirm your app is handling requests asynchronously, you can add a delay in your async functions and send multiple concurrent requests—Tornado should handle them without blocking. For example:

async def func2():
    await tornado.gen.sleep(2)  # Async delay (doesn't block the loop)
    return "Hello from func2!"

When you send two POST requests to /A at the same time, both should finish after ~2 seconds (instead of 4 seconds if it were synchronous).

内容的提问来源于stack exchange,提问作者Hahahahah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 11:57:46