以下是
gunicorn.workers.sync.SyncWorker
类self.handle
方法的代码横截面:
def handle(self, listener, client, addr):
req = None
try:
if self.cfg.is_ssl:
client = sock.ssl_wrap_socket(client, self.cfg)
parser = http.RequestParser(self.cfg, client, addr)
req = next(parser)
self.handle_request(listener, req, client, addr)
上面的方法执行行:
parser = http.RequestParser(self.cfg, client, addr)
,它返回一个继承自gunicorn.http.parser.RequestParser
的gunicorn.http.parser.Parser
对象,如下所示:
class Parser(object):
mesg_class = None
def __init__(self, cfg, source, source_addr):
self.cfg = cfg
if hasattr(source, "recv"):
self.unreader = SocketUnreader(source)
else:
self.unreader = IterUnreader(source)
self.mesg = None
self.source_addr = source_addr
# request counter (for keepalive connetions)
self.req_count = 0
def __iter__(self):
return self
def __next__(self):
# Stop if HTTP dictates a stop.
if self.mesg and self.mesg.should_close():
raise StopIteration()
# Discard any unread body of the previous message
if self.mesg:
data = self.mesg.body.read(8192)
while data:
data = self.mesg.body.read(8192)
# Parse the next request
self.req_count += 1
self.mesg = self.mesg_class(self.cfg, self.unreader, self.source_addr, self.req_count)
if not self.mesg:
raise StopIteration()
return self.mesg
next = __next__
上面的对象
gunicorn.http.parser.Parser
定义了self.__iter__
和self__next__
特殊方法,是iterables
和iterators
的协议。然而,在方法 parser
中定义的保存返回对象的局部变量 self.handle
是 gunicorn.http.parser.RequestParser
的实例,而不是 iterator
,正如 pdb
的输出所证实的那样(参见下面的 stracktrace)调试器:<class 'gunicorn.http.parser.RequestParser'>
。在已分配给 parser
的返回对象之后,该方法执行行:req = next(parser)
,并传递 parser
作为其参数。
内置函数
next()
不应该接受第一个参数作为迭代器吗? parser
不是 iterator
,而是 gunicorn.http.parser.RequestParser
类的实例。以下是next()
的Python文档:
next(iterator)
next(iterator, default)
Retrieve the next item from the iterator by calling its __next__() method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration is raised.
我已经运行
pdb
来生成堆栈跟踪,以确认当 req=next(parser)
行执行时实际发生的情况。它落入self.__next__
的方法gunicorn.http.parser.Parser
。应该返回 self.__iter__
的方法 iterator
根本没有被调用,实际上我将其从代码中注释掉了,代码运行起来没有任何复杂性。 self.__iter__
这个方法到底是必需的吗?
/home/humbulani/django/env/bin/gunicorn(8)<module>()
-> sys.exit(run())
/home/humbulani/django/env/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py(71)run()
-> WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
/home/humbulani/django/env/lib/python3.10/site-packages/gunicorn/app/base.py(264)run()
-> super().run()
/home/humbulani/django/env/lib/python3.10/site-packages/gunicorn/app/base.py(74)run()
-> Arbiter(self).run()
/home/humbulani/django/env/lib/python3.10/site-packages/gunicorn/arbiter.py(226)run()
-> self.manage_workers()
/home/humbulani/django/env/lib/python3.10/site-packages/gunicorn/arbiter.py(602)manage_workers()
-> self.spawn_workers()
/home/humbulani/django/env/lib/python3.10/site-packages/gunicorn/arbiter.py(673)spawn_workers()
-> self.spawn_worker()
/home/humbulani/django/env/lib/python3.10/site-packages/gunicorn/arbiter.py(640)spawn_worker()
-> worker.init_process()
/home/humbulani/django/env/lib/python3.10/site-packages/gunicorn/workers/base.py(144)init_process()
-> self.run()
/home/humbulani/django/env/lib/python3.10/site-packages/gunicorn/workers/sync.py(126)run()
-> self.run_for_one(timeout)
/home/humbulani/django/env/lib/python3.10/site-packages/gunicorn/workers/sync.py(70)run_for_one()
-> self.accept(listener)
/home/humbulani/django/env/lib/python3.10/site-packages/gunicorn/workers/sync.py(32)accept()
-> self.handle(listener, client, addr)
/home/humbulani/django/env/lib/python3.10/site-packages/gunicorn/workers/sync.py(140)handle()
-> req = next(parser) # self.msg attribute
> /home/humbulani/django/env/lib/python3.10/site-packages/gunicorn/http/parser.py(37)__next__()
-> if self.mesg and self.mesg.should_close():
我们将非常感谢您的回复。
next
作用很少;你可以想象它的实现是这样的:
_sentinel = object()
def next(itr, default=_sentinel):
try:
return itr.__next__()
except StopIteration:
if default is _sentinel:
raise
return default
所以
next(parser)
只是调用 parser.__next__
,因为 parser
是一个迭代器:它是定义 Parser
的类 (__next__
) 的实例。
next
不接受的是一个不是迭代器的类的实例。通过定义 __iter__
,Parser
恰巧 also(像所有其他迭代器一样)是一个 iterable。您可以成为可迭代对象而不是迭代器(如 list
),但反之则不然。