Log that a request was responded to after respondi

2019-08-06 13:33发布

This probably is a very noobish question, but I want to make sure my code is doing what I think it's doing.

Here's what I'm after - get a request, make a decision, respond to it the request with the decision, and only then log it. The sequence is important because writes can be slow and I want to make sure that a response is published before any writes take place.

Here's the sample code:

class ConferenceGreetingHandler(webapp.RequestHandler):
def get(self):
    self.post()

def post(self):

    xml_template(self, 'templates/confgreeting.xml')

    new_log = Log()
    new_log.log = 'test'
    new_log.put()

I think I'm serving a response before logging, is this in fact true? Also, is there a better way to do this? Again, sorry for super-noobishness...

EDIT: Here's the template:

def xml_template(handler, page, values=None):
    path = os.path.join(os.path.dirname(__file__), page)
    handler.response.headers["Content-Type"] = "text/xml"
    handler.response.out.write(template.render(path, values))

2条回答
欢心
2楼-- · 2019-08-06 14:10

Much depends on what xml_template does. If it does a self.response.write(...), then the handler has done it's part to serve a response. The webapp framework does the rest once your handler completes normally.

I'm not sure what your "better way" question refers to, but two things stand out.

First, logger.warn("test") will write to the system log, rather than creating a Log instance that you have to (possibly) track down and delete later.

Second, if you're going to use xml_template widely, make it an instance method. Create your own subclass of webapp.RequestHandler, put xml_template there, and then subclass that for your specific handlers.

Updated: I overlooked the part about wanting to get the response out before doing writes. If you're suffering from slow writes, first look very carefully at whether the Entity being writing to is overindexed (indexed on fields that would never be queried against). If that wasn't enough to get performance into an acceptable range, the advice Nick lays out is the way to go.

查看更多
太酷不给撩
3楼-- · 2019-08-06 14:12

No matter what you do, App Engine will not send a response to a user until your handler code completes. There's currently no way, unfortunately, to tell App Engine "send the response now, I won't output any more".

You have a few options:

  1. Just put the log entry synchronously. Datastore writes aren't hugely expensive with respect to wallclock latency, especially if you minimize the number of index updates needed.
  2. Enqueue a task queue task to write the log data. If you use pull queues, you can fetch log entries and write them in batches to the datastore from another task or the backend.
  3. Start the datastore write for the log entry as soon as you have the relevant data, and use an asynchronous operation, allowing you to overlap the write with some of your processing.
查看更多
登录 后发表回答