본문 바로가기

Back_End(Ruby on Rails)

Rails Application Request/Response Cycle(레일즈 애플리케이션은 서버에서 어떻게 작동할까?)

반응형

하드웨어 서버 영업을 할 때 부터 항상 궁금했던건데, 물리 서버에서 어떻게 백엔드 애플리케이션이 동작을 하는지가 항상 궁금했었다. 그런 동기에서 Rails Application을 작동 방식, 즉 서버의 핵심인 Request/Response Cycle을 정리해보았습니다. 크게 아래와 같은 1~8단계로 Cycle로 작동하며, 각 단계 위에서 Object가 새로 만들어지면서 정의된 method들을 Call한다고 볼 수 있습니다. 참고로, 같은 컨트롤러 클래스의 심지어 같은 Action Method를 요청하는 복수의 Request들이 있을 때 Object들은 어떻게 생성될까요? 이떄는 각 요청 당 Object들이 따로 만들어집니다. (the controller class creates a new instance of itself, and forwards the arguments to the #dispatch instance method. This means each request is handled by a new, clean controller object.)

Prerequisite: Rack

1단계: The Rack Entry Point: 다른 object 를 생성하기 위한 베이스 object로 생각합니다.

2단계: MiddleWare -> 많은 액션 디스패쳐가 랙 미들웨어로서 실행된다.(Many of Action Dispatcher's internal components are implemented as Rack middlewares)

Rack middleware are app objects that call other app objects. This allows middleware to do two things: Once the request has passed through all 20 middleware objects, it then enters the router. 미들웨어는 요청을 받아서 중간에 척추처럼 쭉 타고 실행되는 애플리케이션이라고 볼 수 있다.

3단계: Routing

  • ActionDispatch::Routing::RouteSet 인스턴스-> (request env -> ActionDispatch::Request Object 로 변환)(whereas env hash: generic Representations of a web Req -> 이 Request object가 dispatch할 적정한 route를 찾는다. 물론 이에 매칭되는 컨트롤러 클래스와 그 안에 매칭되는 Action Method까지 포함해서 lookup한다.
  • lookup한 후, 우선 비어있는 reponse object를 만든다. (an instance of ActionDispatch::Response)
  • 마지막으로는 controller class가 해당 클래스 매서드인 #dispatch로 실행이 된다. (controller_class.dispatch(action, request, response)
    • 모든 app에 있는 route set ActionDispatch::Routing::Routeset 에 런타임 동안 인스턴스안에 저장되어있다.
    • How Routing Process Works

4단계: The Controller

    • Controller의 엔트리 포인트는 routing 과정의 마지막에 있었던 #dispatch class method 이다.
    • 특이사항은 각 컨트롤러 클래스마다 또 독자적인 stack of middleware가 있다.컨트롤러 클래스 매서드인 dispatch method 참조
    • Controller class가 스스로(즉 클래스 매서드로) 새로운 인스턴스를 만들고, 이때의 Argument를 dispatch instance method 로 forward 해준다.
    • 아래부터 순서대로 dispatch class method(먼저 실행), dispatch instance method
    • 아래에 process(name) 과정에서 correct action method를 call하는 것임
    • 근데 process(name)에서 action method를 콜 하기 전에 deep inheritance hierarchy에 따라 여러가지 method들이 사이에서 콜 된다.
    • 즉, dispatch instance method와 action method 사이 Call Stack에서 여러 method들이 먼저 call된다. 중요한 점은 single controller object마다 이 모든 methods가 call된다는 점임..!

 

dispatch 클래스 Method의 정의 
dispatch instance method의 정의, dispatch class method 이후에 실행 됩니다.

5단계: Rendering

    • 먼저 아래와 같이 컨트롤러에서 Implement 되는 render 코드를 보자.
    • class ExampleController < ApplicationController
        def index
          render plain: 'Hello, world!'
        end
      End
    • 위와 같이 내가 무엇을 랜더링 하든 간에 해당 index 함수의  실행 결과(응답 결과, response)는 response object의 body,(즉, response.body) 에 저장됩니다. 또한, response object 안에 Content-Type이라는 HTTP header에 text/plain형식으로 값이 들어갑니다.

6단계: Leaving The Controller:  컨트롤러가 예정된 Action Method 를 Call 한 뒤, Rails Applicatioin 의 Call Stack은 해당 컨트롤러 클래스의 하이라키(계층 질서)에 따라 아래와 같은 순서로 동작합니다.  

  1. After_action callback method call
  2. Instrumentation finishes: 여기서 instrumentation process_action 과 관련되 있는 hook들을 제공합니다. Redirect_to , cleanup_view_runtime 같은 해당 액션과 관련된 method들이 있습니다.
    • Rails 에서의 Instrumentation process_action과 관련이 있는 ActionController Namespace 내에 정의되어있으며, class method로 이루어져 있습니다.
  3. Global I18n config is restored to its original value: 레일즈 글로벌 I18n 모듈이 원래의 오리지널 값으로 다시 회복합니다.
  4. Flash messages are stored within the session: 플래시 메시지가 세션에 저장됩니다. 여기서 Flash Message Controller Action Method 내에서 정의된 경고 창 등을 발생하는 method로 생성된 것을 의미합니다.

7단계: Leaving Routing

    • Routing 은 단순히 controller에서 리턴 값으로 돌려주는 것을 Middleware로 그대로 보내줍니다. (, response.headers X-Cascade: pass 를 포함하고 있지 않다면..!)
    • 가끔 컨틀롤러로부터 반환되는 헤더에서 또 다른 Routing을 향하는 요청을 보낸다면, 그 요청을 Re-dispatch 합니다. 즉, 또 다른 Route 를 찾는 시도를 하게 됩니다.

8단계: Leaving Middleware

    • Routing 이후, Rack Response 배열이 모든 미들웨어를 통해서 반환됩니다. , 실행된 Rails Application 이 요청을 받아서 적절한 action method가 실행되고, 이후에 일련의 과정을 거치면서 모든 미들웨어를 한번씩 찍으면서 응답값을 반환해주는 것입니다.

결론(Conclusion): Rails 의 요청/응답 주기는 Rack을 기본으로 합니다.  , root appliaction object rack app 입니다. 이 오브젝트 위에서 이제 다른 object들이 생성되는 것입니다.. 그리고 이 위에 Rails의 각종 기능들이 Rack Middleware 위에서 실행됩니다. 아하.. 이런 원리로 Rails Application이 서버에서 하루종일 켜져있어서 실행되는구나. 

 

*참고: Dispatcher 란? 

사용자가 프로그램을 실행하면 프로세스가 생성되고 Ready상태가 된다.(Ready Queue) 그 후 스케줄러가 Ready Queue에 있는 프로세스 중 하나를 프로세서(CPU)가 사용가능한 상태가 될 때 CPU를 할당해준다.

이를 준비상태(Ready)에서 실행상태(Running)로 상태전이(State Transition)된다고 한다. 이 과정을 디스패칭(dispatching)이라고 하고 디스패처(dispatcher)가 이 일을 수행한다. (source: https://www.crocus.co.kr/1406 )

 

source: https://www.rubypigeon.com/posts/examining-internals-of-rails-request-response-cycle/

 

Examining The Internals Of The Rails Request/Response Cycle

Come with me on a journey through the internals of Rails, as we trace a request from the web server to the controller action method, and follow the response back again. This will give you a glimpse of how Rails works under the hood, hopefully exposing some

www.rubypigeon.com

 

반응형