[Django] 원본 해석 Django 시작 및 접근 프로세스 (3)
26169 단어 Django는 입문부터 정통까지.
전언
[Django] 원본 분석django의 시작과 접근 과정(二)에서 우리는 Django가 실제적으로 WSGIRequestHandler를 self로 하는 것을 알게 되었다.RequestHandlerClass 및 self.응용 프로그램은 WSGIHandler 클래스로 시작하고 socketserver입니다.TCPServer 서비스.이 편은 우리가 socketserver로BaseServer.serve_forever는 입구이고 이어서 Django의 방문 과정을 분석합니다.
socketserver.BaseServer.serve_forever
def serve_forever(self, poll_interval=0.5):
"""Handle one request at a time until shutdown.
Polls for shutdown every poll_interval seconds. Ignores
self.timeout. If you need to do periodic tasks, do them in
another thread.
"""
# threading.Event()
# wait(tiemout=NOne),
# clear, False, wait
# set, True, wait
self.__is_shut_down.clear()
try:
# XXX: Consider using another file descriptor or connecting to the
# socket to wake this up instead of polling. Polling reduces our
# responsiveness to a shutdown request and wastes cpu at all other
# times.
# selector=selectors.PollSelector
with _ServerSelector() as selector:
#
selector.register(self, selectors.EVENT_READ)
#
while not self.__shutdown_request:
# poll_interval
ready = selector.select(poll_interval)
# bpo-35017: shutdown() called during select(), exit immediately.
if self.__shutdown_request:
break
# self._handle_request_noblock()
if ready:
self._handle_request_noblock()
# ,
self.service_actions()
finally:
self.__shutdown_request = False
self.__is_shut_down.set()
위쪽 코드 해독을 통해django가 사용자의 방문 행위를 감청한 후self.handle_request_Block 방법을 처리하고 다음에 이 방법을 계속 해석합니다.
socketserver.BaseServer._handle_request_noblock
def _handle_request_noblock(self):
"""Handle one request, without blocking.
I assume that selector.select() has returned that the socket is
readable before this function was called, so there should be no risk of
blocking in get_request().
"""
try:
# socketserver.BaseServer.get_request(self):return self.socket.accept()
# self.socket = socket.socket(self.address_family, self.socket_type)
# socket socket
request, client_address = self.get_request()
except OSError:
return
# , , True
if self.verify_request(request, client_address):
try:
# socketserver.ThreadingMixIn.process_request
# ,
self.process_request(request, client_address)
except Exception:
#
self.handle_error(request, client_address)
# socket
self.shutdown_request(request)
except:
self.shutdown_request(request)
raise
else:
self.shutdown_request(request)
상기 코드에서 알 수 있듯이 사용자의 접근 요청은'socketserver'에 전달되었다.ThreadingMixIn.process_Request'를 처리하고, 다음은 계속해서 해독하겠습니다
socketserver.ThreadingMixIn.process_request
class ThreadingMixIn:
"""Mix-in class to handle each request in a new thread."""
# Decides how threads will act upon termination of the
# main process
daemon_threads = False
# If true, server_close() waits until all non-daemonic threads terminate.
block_on_close = True
# For non-daemonic threads, list of threading.Threading objects
# used by server_close() to wait for all threads completion.
_threads = None
def process_request_thread(self, request, client_address):
"""Same as in BaseServer but as a thread.
In addition, exception handling is done here.
"""
try:
# socketserver.BaseServer.finish_request
'''
def finish_request(self, request, client_address):
"""Finish one request by instantiating RequestHandlerClass."""
self.RequestHandlerClass(request, client_address, self)
'''
# self.RequestHandlerClass, WSGIRequestHandler
self.finish_request(request, client_address)
except Exception:
#
self.handle_error(request, client_address)
finally:
# , socket
self.shutdown_request(request)
def process_request(self, request, client_address):
"""Start a new thread to process the request."""
#
t = threading.Thread(target = self.process_request_thread,
args = (request, client_address))
# False,
t.daemon = self.daemon_threads
if not t.daemon and self.block_on_close:
if self._threads is None:
self._threads = []
#
self._threads.append(t)
#
'''
start -> _bootstrap -> _bootstrap_inner > run -> process_request_thread -> finish_request -> WSGIRequestHandler
'''
t.start()
...
상기 코드에서 알 수 있듯이 요청 내용은
django.core.servers.basehttp.WSGIRequestHandler
처리에 맡겼습니다. 다음은 계속해서 그것을 해석하겠습니다.django.core.servers.basehttp.WSGIRequestHandler.init
# socketserver.BaseRequestHandler.__init__
def __init__(self, request, client_address, server):
self.request = request
self.client_address = client_address
# django WSGIServer
# httpd_cls = class WSGIServer(socketserver.ThreadingMixIn,WSGIServer):...
self.server = server
# socketserver.StreamRequestHandler.setup
# socket , socket
self.setup()
try:
#
# django.core.servers.basehttp.WSGIRequestHandler.handle
self.handle()
finally:
#
self.finish()
위에서 알 수 있듯이 요청 처리가'django'에 들어갔습니다.core.servers.basehttp.WSGIRequestHandler.handlecore.servers.basehttp.WSGIRequestHandler'판독은 계속됩니다.
django.core.servers.basehttp.WSGIRequestHandler
class WSGIRequestHandler(simple_server.WSGIRequestHandler):
...
def handle(self):
#
self.close_connection = True
#
self.handle_one_request()
while not self.close_connection:
self.handle_one_request()
try:
# socket ,
self.connection.shutdown(socket.SHUT_WR)
except (socket.error, AttributeError):
pass
def handle_one_request(self):
"""Copy of WSGIRequestHandler.handle() but with different ServerHandler"""
# socket
self.raw_requestline = self.rfile.readline(65537)
if len(self.raw_requestline) > 65536:
self.requestline = ''
self.request_version = ''
self.command = ''
self.send_error(414)
return
# , , , , ,
# content_type=keep-alive, self.close_connection False
if not self.parse_request(): # An error code has been sent, just exit
return
# ServerHandler
handler = ServerHandler(
self.rfile, self.wfile, self.get_stderr(), self.get_environ()
)
handler.request_handler = self # backpointer for logging & connection closing
# , ,Django TCPServer ‘httpd.set_app(wsgi_handler)’
# self.application, django settings ‘WSGI_APPLICATION’,
# ‘django.core.handlers.wsgi.WSGIHandler’
# run 'wsgiref.handlers.BaseHandler.start_response' ‘WSGIHandler’ __call__ 。
handler.run(self.server.get_app())
django.core.servers.basehttp.ServerHandler.run
def run(self, application):
"""Invoke the application"""
# Note to self: don't move the close()! Asynchronous servers shouldn't
# call close() from finish_response(), so if you close() anywhere but
# the double-error branch here, you'll break asynchronous servers by
# prematurely closing. Async servers must return from 'run()' without
# closing if there might still be output to iterate over.
try:
# self.environ
self.setup_environ()
# WSGIHandler.__call__
self.result = application(self.environ, self.start_response)
# self.result, ServerHandler self.wfile
self.finish_response()
except (ConnectionAbortedError, BrokenPipeError, ConnectionResetError):
# We expect the client to close the connection abruptly from time
# to time.
return
except:
try:
self.handle_error()
except:
# If we get an error handling an error, just give up already!
self.close()
raise # ...and let the actual server figure it out.
위의 원본 코드 해독을 통해 우리는 요청 내용이django에 들어갔다는 것을 알았다.core.handlers.wsgi.WSGIHandler.__call__처리하다.다음 편에서는 WSGIHandler. 에서call__방문 과정의 원본 코드를 계속해서 해독하다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[Django] 원본 해석 Django 시작 및 접근 프로세스 (4)Django 액세스 프로세스(둘) Django 방문 과정 (1) 에서 우리는 요청 내용이 django에 들어갔다는 것을 알게 되었다.core.handlers.wsgi.WSGIHandler.__call__처리를 진행하...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.