[Django] 원본 해석 Django 시작 및 접근 프로세스 (3)

Django 액세스 프로세스 (1)
전언
[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__방문 과정의 원본 코드를 계속해서 해독하다.

좋은 웹페이지 즐겨찾기