How Nitrogen processes requests – part 2

Context

In the last post we discussed how Nitrogen inits a new Context for each request and stores it in the process dictionary.

Conceptually, Nitrogen uses Context to pass the page state from the server to browser and then, on postback, it passes this state from the browser back to the server and restores it to the new instance of Context.

This is hugely important, when Nitrogen generates the html for the page, it also serializes whatever data are found in #page_context{} and in the Handlers list of the Context and passes it to the browser in the Response message and then stores it on the page in ‘pageContext’ variable. These data are of course hidden but if you inspect the page in Firebug you can find it in the script section.

Screen Shot 2013-02-20 at 23.18.28

Context record looks like this:

Context = #context {
        request_bridge = RequestBridge,
        response_bridge = ResponseBridge,
        page_context = #page_context { series_id = wf:temp_id() },
        event_context = #event_context {},
        handler_list = [
            % Core handlers...
            make_handler(config_handler, default_config_handler),
            make_handler(log_handler, default_log_handler),
            make_handler(process_registry_handler, nprocreg_registry_handler),
            make_handler(cache_handler, default_cache_handler),
            make_handler(query_handler, default_query_handler),

            % Stateful handlers...
            make_handler(session_handler, simple_session_handler),
            make_handler(state_handler, default_state_handler),
            make_handler(identity_handler, default_identity_handler),
            make_handler(role_handler, default_role_handler),

            % Handlers that possibly redirect...
            make_handler(route_handler, dynamic_route_handler),
            make_handler(security_handler, default_security_handler)
        ]
    }

as you can see it has keys for Request/Response Bridge, #page_context{} – which describes html elements that you have on the page and which gets sent to the browser in serialized form, #event_context{} – which describes the javascript actions. It also has a list of handlers – which are the references to the modules which implement certain behaviors and their state, this data also get sent to the browser in serialized form.

 #handler_context {
        name=Name,
        module=Module,
        state=[]
    }.

The example of the handler could be a query_handler, which runs when you use API function wf:q(AtomKey). The implementation logic in the query_handler.erl knows how to retrieve the element from the pageContext and how to find its value. Lots of Nitrogen API functions are just wrappers around corresponding Handler modules. E.g. looking into module wf.erl you can see things like:

params() ->
    query_handler:get_params().
%%% EXPOSE LOG_HANDLER %%%
info(String, Args) -> 
    ok = log_handler:info(String, Args).
%%% EXPOSE SESSION_HANDLER %%% 
session(Key) -> 
    _Value = session_handler:get_value(Key).
%%% EXPOSE STATE_HANDLER %%%
state(Key) -> 
    _Value = state_handler:get_state(Key).

which allow you to get/set values in the Context via corresponding handler calls.
The really cool part is that handlers could be replaced by your own implementations. If, for example, you need to change Nitrogen logging you can implement your own logic and plug it in Nitrogen during initialization.

You can find the documentation page for Nitrogen Handlers here.

So, at this checkpoint we have :

  • RequestBridge object which contains the parsed http request.
  • new instance of Context object which is stored in process dictionary

Now, we can run Nitrogen to build a html which will be returned to the client:

 {ok, Req2} = nitrogen:run()

calls:

run() ->
    wf_core:run().

which calls the following code (slightly modified for clarity):

run() ->
    Request = wf_context:request_bridge(),
    Response = wf_context:response_bridge(),
    try 
         run_catched()
    end.

I have to emphasize that Nitrogen in this instance is used purely as html building library. It is not doing any page routing and it is not even running in its own process but using the process started by Cowboy.

Please correct me if you find something wrong with the above description.

I will continue the explanation in the next post.

About these ads
This entry was posted in Cowboy, Erlang, Nitrogen, Simple_Bridge and tagged , , , , . Bookmark the permalink.

One Response to How Nitrogen processes requests – part 2

  1. Pingback: How Nitrogen processes requests – part 3 | R.Shestakov

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s