0

guys. I'm reading web.py source code to understand how WSGI frameworks work.

When reading application.py module, I wonder why call self._cleanup in cleanup which is a generator function.

I searched reasons to use generator, like this, but I'm not sure why use generator here.

Here is the code block:

def wsgi(env, start_resp):
    # clear threadlocal to avoid inteference of previous requests
    self._cleanup()

    self.load(env)
    try:
        # allow uppercase methods only
        if web.ctx.method.upper() != web.ctx.method:
            raise web.nomethod()

        result = self.handle_with_processors()
        if is_generator(result):
            result = peep(result)
        else:
            result = [result]
    except web.HTTPError, e:
        result = [e.data]

    result = web.utf8(iter(result))

    status, headers = web.ctx.status, web.ctx.headers
    start_resp(status, headers)

    def cleanup():
        self._cleanup()
        yield '' # force this function to be a generator

    return itertools.chain(result, cleanup())
Community
  • 1
  • 1
Zhongwei Sun
  • 125
  • 1
  • 7

1 Answers1

1

What itertools.chain(result, cleanup()) does is effectively

def wsgi(env, start_resp):
    [...]

    status, headers = web.ctx.status, web.ctx.headers
    start_resp(status, headers)

    for part in result:
         yield part
    self._cleanup()
    # yield '' # you'd skip this line because it's pointless

The only reason I can imagine why it's written in such a weird way is to avoid that extra pure Python loop for a little bit of performance.

Jochen Ritzel
  • 104,512
  • 31
  • 200
  • 194
  • Thanks for your response. It's reasonable. I rethink about the code, another reason I guess is returning result to client as soon as possible, then do cleanup job at last to avoid the delay. Not sure whether it's right. – Zhongwei Sun May 03 '11 at 15:53