-
Notifications
You must be signed in to change notification settings - Fork 24
Mach II 1.6 Bootstrapper Enhancement
- The Problem
- Exploring the Solutions
- The Solution
- Additional Information and Considerations
- In Closing
By Peter J. Farrell (peter@…)
Integrating third-party (such as MachBlog) that use sessions require you
to copy and paste onSessionStart
/ onSessionEnd
specific code into
your Application.cfc/cfm. While this may be simple to do, it becomes a
tedious and error prone process when you want to upgrade your module to
a new version.
This would also apply if another team of developers maintain the code to the module you integrate with your application. Module integrating should be as easy as drag-n-drop by adding the module configuration file to your base Mach-II XML configuration file. Currently, this is not possible when integrating modules.
Another problem is that Mach-II applications require users to manually call methods in the mach-ii.cfc boostrappers when using Applications. These could easily be streamlined for standard Mach-II applications, allowing developers to override default options by overriding the method in their Application.cfc.
In the mind of this developer, there are three solutions to this problem that all vary in their degree easiness integration. Since we are aiming for easy integration, I hope you agree in my conclusions.
-
The current approach - documenting what code to copy and paste into the bootstrapper. This brings to a problem that documentation usually does not exist or is out dated. Also, a developer must watch for any changes to
onSessionStart/End
and copy them into their Application.cfc when newer versions of code are released. This approach is clumsy and error prone. -
A module could encapsulate
onSessionStart/End
code in a Mach-II property CFC. This keeps the required code within the module, however a developer still must place a line of code in their Application.cfc that calls this property and executes the desiredonSessionStart/End
code. This is a better approach than solution from ticket #1 (trac-wiki) "defect: Redirect Does Not Work on BlueDragon (closed: fixed)"), but it still requires the developer to copy a code. -
Add a construct in Mach-II for
onSessionStart/End
that registers itself with Mach-II. The Mach-II Application.cfc bootstrapper would automatically call any registeredonSessionStart
oronSessionEnd
application events. This is the best approach as code remains encapsulated as part of the module (this even applies to base applications) and registration of the application event is automatic. No module integration is required other than registering the module config file in the base configuration file and potential override a few elements in the override XML.
Implement the onSessionStart
and onSessionEnd
methods in the
mach-ii.cfc bootstrapper for Application.cfc. If sessions are turned off
in the Application.cfc, these methods are ignored by the ColdFusion
engine anyways. In these application event methods, there is code that
makes a call to AppManager to start or end a session. This calls any
registered onSessionStart
or onSessionEnd
methods in any plugin
points that define an onSessionStart
and/or onSessionEnd
method.
This requires the addition of two new plugin points - onSessionStart
and onSessionEnd
. This solution is backwards compatible and does not
require a developer use this integration unless they wish.
<cfcomponent
displayname="SimplePlugin"
extends="MachII.framework.Plugin"
output="false"
hint="A simple Plugin example.">
<!---
PROPERTIES
--->
<!---
INITIALIZATION / CONFIGURATION
--->
<cffunction name="configure" access="public" returntype="void" output="false"
hint="Configures the plugin.">
</cffunction>
<!---
PUBLIC FUNCTIONS
--->
... preProcess, preEvent, postEvent, preView, postView,
postProcess and handleException plugin points ...
<cffunction name="onSessionStart" access="public" returntype="void" output="false">
... code to run when a session starts ...
</cffunction>
<cffunction name="onSessionEnd" access="public" returntype="void" output="false">
<cfargument name="sessionScope" type="struct" required="true"
hint="Session scope is passed in as required by the onSessionEnd event in Application.cfc." />
... code to run when a session ends (must use the arguments.sessionScope
instead of accessing the session scope directly) ...
</cffunction>
</cfcomponent>
- The
onSessionStart
andonSessionEnd
plugin points will not have access to the event object as they are run before a Mach-II request starts or in the case ofonSessionEnd
after a user has left your website (e.g. no request is currently running). -
onSessionStart/End
is run in the base application first followed by all registered modules. The order of execution in the modules is undefined.
Proposed Additions to mach-ii.cfc Boostrapper:
- onApplicationStart
- onRequestStart
- onSessionStart
- onSessionEnd
With sensible defaults, this would allow an basic Application.cfc to go from this:
<cfcomponent
displayname="Application"
extends="MachII.mach-ii"
output="false"
hint="Performs Application.cfc functionality.">
<!---
PROPERTIES - APPLICTION.CFC SPECIFIC
--->
<cfset this.name = "m2harness" />
<cfset this.applicationTimeout = CreateTimeSpan(30,0,0,0) />
<cfset this.clientManagement = FALSE />
<cfset this.sessionManagement = TRUE />
<cfset this.sessionTimeout = CreateTimeSpan(0,0,30,0) />
<cfset this.setClientCookies = FALSE />
<!---
PROPERTIES - MACH-II SPECIFIC
--->
<cfset MACHII_CONFIG_PATH = ExpandPath("/machiitest/config/mach-ii.xml") />
<cfset MACHII_APP_KEY = this.name />
<cfset MACHII_CONFIG_MODE = -1 />
<!---
PUBLIC FUNCTIONS
--->
<cffunction name="onApplicationStart" access="public" returntype="boolean" output="false">
<cfsetting requestTimeout="#REQUEST_TIMEOUT#" />
<cfset LoadFramework() />
<cfreturn TRUE />
</cffunction>
<cffunction name="onRequestStart" access="public" returntype="void" output="true">
<cfargument name="targetPage" type="string" required="true" />
<cfif arguments.targetPage EQ "/index.cfm">
<!--- Handle Mach-II request --->
<cfset handleRequest() />
</cfif>
</cffunction>
</cfcomponent>
To this:
<cfcomponent
displayname="Application"
extends="MachII.mach-ii"
output="false"
hint="Performs Application.cfc functionality.">
<!---
PROPERTIES - APPLICTION.CFC SPECIFIC
--->
<cfset this.name = "m2harness" />
<cfset this.applicationTimeout = CreateTimeSpan(30,0,0,0) />
<cfset this.clientManagement = FALSE />
<cfset this.sessionManagement = TRUE />
<cfset this.sessionTimeout = CreateTimeSpan(0,0,30,0) />
<cfset this.setClientCookies = FALSE />
<!---
PROPERTIES - MACH-II SPECIFIC
--->
<!--- Set the path to the application's mach-ii.xml file --->
<cfset MACHII_CONFIG_PATH = ExpandPath("/m2harness/config/mach-ii.xml") />
<cfset MACHII_APP_KEY = this.name />
<cfset MACHII_CONFIG_MODE = -1 />
<cfset MACHII_ONLOAD_REQUEST_TIMEOUT = 100 />
</cfcomponent>
The addition of onSessionStart
/ onSessionEnd
integration would not
change the backwards compatibility of the framework nor would it force
developers to use this new feature. However, the addition of this
enhancement would developers to integrate third-party modules into a
base application with ease and/or to encapsulate session application
events into Mach-II rather than maintaining application event code in
their Application.cfc file.