-->

How to wait for the calling of request.finish() in

2019-08-17 08:04发布

问题:

In my python file I have two handler classes: MainHandler(tornado.web.RequestHandler) and WebSocketHandler(tornado.web.WebSocketHandler). In the MainHandler class I do the following code in the get method:

class MainHandler(tornado.web.RequestHandler):
   #some code
   def get(self):
      #some code
      mainHandler_dict[chan] = self
      await self.finish() #line of code that would do the waiting somehow

So I store the request in a global dictionary so I can call request.write() and request.finish() in the on_message method of the WebSocketHandler class:

class WebSocketHandler(tornado.websocket.WebSocketHandler):
   def on_message(self, message):
      #some code 
      request.write(body)
      request.finish()

I get the "request" variable from the global dictionary and try to call write(), but the following error occurs: RuntimeError: Cannot write() after finish()

I think finish() is being automatically called after the end of the get method in the MainHandler class. So is there a way for the requestHandler to keep on "waiting" while I don't call the request.finish() somewhere through the file?

回答1:

You should probably handle this the other way around; don't store "the request", try to keep it alive somehow, and write to it from elsewhere, but rather let the request handler wait for the value you need to become available. E.g.:

class MainHandler(RequestHandler):
    async def get(self):
        value = await magic()
        self.write(value)

Now, how to handle the "magic" part depends a bit where that value comes from and what's at your disposal, but let's illustrate with a simple Future:

async def get(self):
    futures[chan] = asyncio.Future()
    value = await futures[chan]
    self.write(value)

And elsewhere:

futures[chan].set_result(42)