Question

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?

Was it helpful?

Solution 2

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top