Overview

An Ex-nunc application is a compiled executable that handles HTTP requests received through a connector (CGI or FastCGI) from the Web server. It relies on OcamlNet to manage low-level communication with the Web server, to retrieve preprocessed parameters from the request, and to write the XHTML response to a transactional output channel. The Ex-nunc framework offers a higher level of abstraction to the programmer, because it takes care of some of the most common tasks required by Web applications.

Request handling

The following diagram shows how the request flows from the Web browser to the Ex-nunc application server, and how the response gets back to the client.

Request flow diagram

The browser posts an HTTP request to the Web server, that forwards it to the application through the connector. The Ex-nunc server process the request and sends back an HTTP response containing the XHTML page that will show on the client.

Page dispatcher

The page to be served is determined server side: the Web browser points simply to the application executable and does not directly request a specific page. The first request in each session will show the start page, a page without parameters, whose name is specified in the application configuration file. The XHTML page served back to the client will contain all the navigation information (current page name and parameters), stored in hidden form fields. When the users submits the form, the application server will retrieve the navigation information, and will be able to determine which page is to be displayed. This way, there is no need to build a Web server module (e.g., an Apache module, or an IIS ISAPI filter) to handle the xnunc extension, simplifying the overall architecture, and permitting the use of standard connectors. Moreover, there is no need to deploy the template files to the server (or an empty placeholder), therefore simplifying the deploy of the application, because the Web server will not be queried for a specific resource file, and there is no risk to obtain a "file not found" (404) error. If any error occurs during the request processing, a customizable error page, whose name is specified in the application configuration file, will show up.

Page life cycle

When a request is received by an Ex-nunc application, after the page dispatcher has determined which page to show, the selected page runs through a life cycle composed by a series of processing steps, depicted by this flowchart (see also the equivalent UML state machine diagram.)

Ex-nunc pages

From the runtime perspective, each page is an instance of an OCaml class that implements the page_behavior interface. The class implementation is generated from the Ex-nunc template. The class constructor is stored into a collection and retrieved using the template name as the key.

Initialization

After the object, representing the current page, has been constructed, its init method is called. If the current page is the first page served in a session, the next step will be the initialization of page parameters. Otherwise, the session was already created and is ready to be loaded.

Session loading

The load_session method fulfills the task of retrieving session data from the configured storage (e.g., server memory, or a hidden field). After restoring session data, the runtime will load page parameters.

Page parameters initialization

If the current page is served for the first time, the page parameters will be initialized to values passed by the page dispatcher or by the calling page (as the consequence of a page change action). Now, the page state is fully restored and the next step is to build the page structure. Otherwise, if the page is resulted from a form submission, the runtime will load current page parameters, reading them from a hidden field. The next step is to validate user input.

User input validation

The validation process is started building the input validator collection, calling the build_validator_collection method. If the page is valid (i.e., the output of is_valid is true), then the runtime will read user input and store it into form parameters. Otherwise, user input will be ignored, and form parameters will maintain their default value.

User input reading

The runtime invoke the read_user_input method. This method will populate form parameters, the OCaml record containing the strongly typed form field values, with values entered by the user. This step completes the page state loading. Next, the runtime will build the page structure.

Page structure building

The page structure is the tree data structure that stores all the page elements composing the page. It is built by the Build_page_structure method. Next, if this is the first invocation for the current page, the runtime will be ready to persist the page state. Otherwise, the events, the user may have triggered, must be handled.

Handling user interface events

When the user submits a form, he may trigger a series of events, handled by one or more callback functions. The handle_ui_events methods executes the associated callbacks. Next, the runtime will handle page changing.

Page changing

As a consequence of an event triggered by a user, a page change may be required. To achieve this, the target page name and parameters must be specified. If the target page is different from the current page, the new page is served, restarting from the initialization step. Otherwise, the next step is state saving.

State saving

The runtime calls the save_state method, to persist all the page state to the proper storage. The current page and parameters will be saved into hidden fields, while the session data is saved to the configured storage. Then the page is ready to be rendered.

Rendering

The render method is invoked, to produce the XHTML response, which will be written to the transactional output channel provided by OcamlNet.

Completing

The complete method takes care of committing what the rendering step wrote to the transactional output channel. This step ends the process. Now the response is sent back to the client.