求助:确认Tornado异步程序正确性,实现请求异步监听
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
AandBclasses inherit fromtornado.web.Application, but request handlers should always inherit fromtornado.web.RequestHandlerinstead.Applicationis the top-level app instance that routes requests to handlers, not the handler itself. - Missing Async Definitions for
func/func2: You're usingawaiton these functions, but they need to be defined asasyncfunctions (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
funandfunc2, but calledfunc()—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

