Understanding Application Lifetime
Introduction
CppCMS has two core orthogonal concepts:
- Applications - classes derived from
cppcms::application
- the objects that define how the user application handles requests - HTTP Context -
cppcms::http::context
- the context of the request, response, session sessions, cache and many other objects connected to the specific Client-Application interaction.
On each incoming request the Context is created and it is associated with the Application class that handles it.
When the request and response are completed, the context will be destroyed and the application usually continues to run.
CppCMS is designed for high performance, thus it "caches" anything possible. This includes application objects.
Before we begin, it is very important to understand the two distinct types of application:
- Synchronous Applications - the most common type of application: the ordinary applications that are designed to handle normal requests.
- Asynchronous Applications - the special applications that are designed to handle multiple requests and support long pooling.
Synchronous Applications
Single Application
Synchronous applications live in a pool. They are generated by a special cppcms::applications_pool::factory
object
that is mounted to the applications_pool
object.
These objects are long-living objects and once they are created they are usually cached in the pool for future reuse.
Upon an incoming request, the application is fetched from the
pool or a new one is created. The special cppcms::http::context
object is assigned to the application during all request processing,
This request is processed in the thread pool by
calling the application::main()
virtual function
that actually handles the request.
Once the request is completed, this context is unassigned and the application is returned back to the pool for future reuse.
So when you write your own applications, you may assume that their constructors are not called frequently. You should also assume that they will "kept alive" for a long time.
It is good idea to cache some general non-mutable information withing such objects.
Applications with Children
Each application can have multiple child-applications, for example:
blog admin post_editing options_editing display post summary feeds atom rss
Each child application can be connected to the parent
via the add
or attach
member functions
in the constructor. Each application shares its lifetime and its cppcms::http::context
with its parent.
Even though they are different objects and different
classes they are tightly bounded and live
together as long as the topmost-parent lives, blog
in our case.
Asynchronous Applications
Lifetime
Unlike synchronous applications that have multiple instances in the applications pool and are executed in the thread pool, asynchronous applications are designed to handle multiple connections simultaneously, and thus instead of being called in the thread pool per each request, they run exclusively in the main CppCMS Event Loop
Asynchronous applications live as long as their reference counter is not 0. Once the reference counter decreases to 0 the application is destroyed and automatically unmounted from the applications pool.
So in order to keep asynchronous applications alive you need to do one of the following:
Keep a persistent
intrusive_ptr
smart pointer on the application, for example in yourmain()
function.This is suitable for a long running application that exists all the time the service is running.
Make sure that you have event handlers that hold a smart pointer and waiting for the event.
This is usually done by passing
intrusive_ptr
within the event handler.This method is suitable for temporary applications that may represent for example different information channels like chat rooms that may be created or destroyed at some point.
Asynchronous applications and their Children
Each asynchronous application and its children share the same reference counter. Thus if a child is attached or assigned to a parent they will share their references and, for example passing a smart pointer to the child class keeps the entire hierarchy alive.
Basically, similar to the synchronous applications, the parent and all its children "live" and "die" together.
HTTP Context handling
There is once context assigned to the asynchronous application. If the cppcms::application::main()
function completes while the context is still assigned,
it would be automatically detached and complete the
response to the client.
In order to postpone the response, the context should
be manually detached from the application by calling
cppcms::application::release_context()
function.
Now it is your responsibility to keep it as long
as you need and finalize the response by calling
cppcms::http::context::complete_response()
← Event Loop | Top | Thread Safety →