Reputation: 1435
Can anyone explain this behaviour to me?
I have set up a bunch of application scoped settings in onApplicationStart
, and some of them are referred to in onSessionStart
. However, when I enable ORM, it seems that onApplicationStart isn't running at all and thus my onSessionStart method fails.
It took me a while to figure out this was the issue, generally I'll test by hitting onApplicationStart
programatically during development. So it was only after a restart of the service that I found a symptom. Eventually I traced it back to ORM and it's as simple as:
THIS.ormenabled = true; // Error
THIS.ormenabled = false; // Everything peachy
I stripped down the Application.cfc and put some timestamps in the various methods so that I could see what was executing:
<cfscript>
THIS.Name = "TestyMcTestable"
THIS.datasource = 'Test';
THIS.ormenabled = true;
</cfscript>
<cfsetting
requesttimeout="20"
showdebugoutput="false"
enablecfoutputonly="false"
/>
<cfset request.pseudo = Now() />
<cfset sleep(1500)>
<cffunction name="OnApplicationStart" access="public" returntype="boolean" output="false">
<cfset request.application = Now() />
<cfset sleep(1500)>
<!--- Return out. --->
<cfreturn true />
</cffunction>
<cffunction name="OnSessionStart" access="public" returntype="void" output="false">
<cfset request.session = Now() />
<cfset sleep(1500)>
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction name="OnRequestStart" access="public" returntype="boolean" output="false">
<cfargument name="TargetPage" type="string" required="true" />
<cfset request.requeststart = Now() />
<cfset sleep(1500)>
<!--- Return out. --->
<cfreturn true />
</cffunction>
<cffunction name="OnRequest" access="public" returntype="void" output="true">
<cfargument name="TargetPage" type="string" required="true" />
<cfset request.request = Now() />
<cfset sleep(1500)>
<!--- Include the requested page. --->
<cfinclude template="#ARGUMENTS.TargetPage#" />
<!--- Return out. --->
<cfreturn />
</cffunction>
My index.cfm just contains a dump of the request scope. If I remove the orm setting, it all comes back as expected. However with the setting in there, the variable set on application start is missing entirely and it seems onApplicationStart hasn't been run at all.
I'm testing by changing the name of the application inbetween requests, but just to be certain I've restarted the service too.
Am I missing something? Is this documented behavior? I'm running this on Railo - I haven't tested extensively on ACF, but the initial problem occurred there too so I assume it's the same cause.
Can anyone shed any light on this?
Upvotes: 3
Views: 551
Reputation: 1435
Turns out this was a problem with the cfclocation setting. In the original app, it was pointing to an incorrect location. When I stripped the Application.cfc down for testing, I removed this setting - not realising that default behaviour is to traverse the folders from root looking for persistent CFCs. It seems then that the app ran into a problem during that process which bombed out of onApplicationStart, but continued running the other functions in Application.cfc.
One of the guys on the Railo group identified an issue with using pseudo constructors in non-persistent CFCs that are read by the Hibernate engine. I'm not certain if that contributed to this issue, but it seems likely.
Upvotes: 0
Reputation: 2073
OnApplicationStart is only run when the Application is first created in memory and is only run once for the life of the Application unless you explicitly call things like ApplicationStop(); or call the method again, etc. In addition, the variable in the Application scope you set is a request scope variable which only exists for the lifetime of one request. Same with onSessionStart, that request variable will only exist when the user session is created for the first time.
First Request: (ApplicationStart & SessionStart Fire)
struct: request
application {ts '2013-03-20 18:50:17'}
cfdumpinited false
pseudo {ts '2013-03-20 18:50:20'}
session {ts '2013-03-20 18:50:19'}
struct: session
cfid 5600
cftoken a8bf96c34c2cac7a-68400880-E1E6-ACDF-3B204DBBCD9A04A9
session {ts '2013-03-20 18:50:19'}
sessionid TESTYMCTESTABLE_5600_a8bf96c34c2cac7a-68400880-E1E6-ACDF-3B204DBBCD9A04A9
urltoken CFID=5600&CFTOKEN=a8bf96c34c2cac7a-68400880-E1E6-ACDF-3B204DBBCD9A04A9
Second Request: (Application/SessionStart Do Not Fire)
struct: request
cfdumpinited false
pseudo {ts '2013-03-20 18:50:59'}
struct: session
cfid 5600
cftoken a8bf96c34c2cac7a-68400880-E1E6-ACDF-3B204DBBCD9A04A9
session {ts '2013-03-20 18:50:19'}
sessionid TESTYMCTESTABLE_5600_a8bf96c34c2cac7a-68400880-E1E6-ACDF-3B204DBBCD9A04A9
urltoken CFID=5600&CFTOKEN=a8bf96c34c2cac7a-68400880-E1E6-ACDF-3B204DBBCD9A04A9
This was tested on CF9.
application.cfm
<cfcomponent>
<cfscript>
this.Name = "TestyMcTestable";
this.ormenabled = true;
this.datasource = 'cfartgallery';
this.sessionManagement = true;
</cfscript>
<cfset request.pseudo = Now() />
<cfset sleep(1500)>
<cffunction name="OnApplicationStart" access="public" returntype="boolean" output="false">
<cfset request.application = Now() />
<cfset session.application = Now() />
<cfset sleep(1500)>
<!--- Return out. --->
<cfreturn true />
</cffunction>
<cffunction name="OnSessionStart" access="public" returntype="void" output="false">
<cfset request.session = Now() />
<cfset session.session = Now() />
<cfset sleep(1500)>
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction name="OnRequestStart">
</cffunction>
</cfcomponent>
Alternatively if you put your request variables in the OnRequestStart, they will be there every time. Hope this helps.
Upvotes: 0