Lazy Loading of Tenants and Artifacts
Lazy loading is a design pattern used specifically in cloud deployments to prolong the initialisation of an object or artifact until it is requested by a tenant or an internal process. Lazy loading of tenants is a feature that is built into all WSO2 products, which ensures that in an environment with multiple tenants, all tenants are not loaded at the time the server starts. Instead, they are loaded only when a request is made for a particular tenant. If a tenant is not utilised for a certain period of time, it will be unloaded from memory.
Lazy loading of artifacts
Lazy loading of tenants is a default feature available in any WSO2 product instance. Additionally, the Ghost Deployment configuration in the carbon.xml
file allows users to enable lazy loading for deployment artifacts as shown below. When this feature is enabled, the services, applications and other artifacts are first loaded in Ghost form. The actual artifact is deployed only when a request for the artifact is made. Also, if an artifact has not been utilized for a certain period of time, it will be unloaded from memory. Note that this setting is not enabled by default because the Ghost Deployer works only with the HTTP/S transports. That is, if other transports are used, we do not have to enable the Ghost Deployer.
<GhostDeployment> <Enabled>false</Enabled> </GhostDeployment>
When lazy loading of artifacts is enabled for PaaS deployments, lazy loading applies both for tenants as well as a tenant’s artifacts. As a result, for a tenant in a cloud environment, lazy loading is applicable on both levels. Therefore, the associated performance improvement and resource utilization efficiencies are optimal.
Lazy loading of artifacts is an optional feature, which is applicable to some WSO2 products such as WSO2 Application Server. See the product documentation for more information.
Lazy loading implementation
Out of four popular variants (Lazy Initialization, Virtual Proxy, Value Holder, Ghost) of the lazy loading design pattern, the "Value Holder" and "Ghost" variants are adopted and used in the lazy loading implementation in WSO2 Carbon Framework.
Use of Value Holder
A value holder is an object, usually (but not necessarily) with a method by the name getValue
, which the clients invoke to obtain a reference to the real object corresponding to a parameter passed in the method. The ValueHolder
variant is used at the event of loading a tenant. The called method is as follow:
TenantAxisUtils.getTenantConfigurationContext(String tenantDomain)
The getTenantConfigurationContext
method is the equivalent of the getValue
method in the ValueHolder
variant. It takes a tenantDomain
as a reference and returns the ConfigurationContext
, if the tenant is already loaded. If the tenant domain does not have an Axis2 ConfigurationContext
, the method will return a newly created Axis2 ConfigurationContext
. In both the latter mentioned methods, when loading an entire AxisConfiguration
, all artifacts belonging to that particular tenant are also loaded. A more efficient practice is to lazy load those artifacts, by loading them only when it is requested by the system or a tenant. This prevents processing overhead and unnecessary memory usage. This is where the Ghost variant of the lazy loading pattern is used.
Use of GhostDeployer and GhostDispatcher/GhostWebappDeployerValve
When the server starts, you can see all the previously deployed services and web applications listed in its management console. However, these artifacts are only the Ghost instances that maintain references to the actual Instances. GhostDeployer
that handles lazy loading of artifacts, holds a map of deployers for all artifact types.
When a new artifact is deployed, the GhostDeployer
creates a Ghost Axis2 Service containing a special parameter (Ghost Parameter) to distinguish the service as a Ghost service, and then registers that service into the AxisConfig
. When a user requests for a particular service artifact, the GhostDispatcher
, which is an Axis2 dispatching handler, checks the Ghost parameter added to the service to determine if it is the actual artifact or the ghost form. If it is the latter, the actual deployer is called to load the actual service, the rest of the metadata from the registry, service policies and other information regarding the artifact.
GhostWebappDeployerValve
, on the other hand, is used with lazy loading for web applications. It is a Tomcat valve that intercepts the incoming http requests, and does the same work as the GhostDispatcher
in Axis2. It intercepts the incoming web app request, checks for the Ghost parameter in the webapp and loads the actual web application if it is found to be in ghost form.