Application.cfc

219 views
Skip to first unread message

Michael Offner

unread,
Nov 1, 2013, 4:59:32 AM11/1/13
to ra...@googlegroups.com
Perhaps you have seen in the latest 4.1 dev release, that we have started to add coding tips to the admin, like the following, to help you move your settings to application.cfc (only if you like of course).
-------------------------------------------------------------------------------
You can also set this in the Application.cfc as follows:
this.locale = "de_CH"; 
-------------------------------------------------------------------------------
in addition we will add a page to admin (in Railo 4.2) that give you a "application.cfc" based on all your settings that are possible in application.cfc.

For Railo 4.2 we are adding support for some new settings to the application.cfc.
But will not only add new settings to application.cfc, we will also "clean the house", by giving you access to settings only possible in other ways today. like we already did for "locale" and "timezone". today you not only can define this regional settings the following way
-------------------------------------------------------------------------------
setTimezone("PST");
setLocale("de_CH");
-------------------------------------------------------------------------------
you can also do it this way in the application.cfc
-------------------------------------------------------------------------------
this.locale="de_CH";
this.timezone="PST";
-------------------------------------------------------------------------------

i personally never have understand why a setting like "Locale" can only be done with a function and other settings are made inside the application.cfc.

So enough introduction on the topic, let's coming to what is undecided yet and where we would like to get your input. 

We are not sure if we should add the settings possible with the tag <cfsetting> (requesttimeout, showdebugoutput) to the application.cfc as well.
In theory they make no sense in the application.cfc, because this are settings unique to a request, but a request can pass multiple application.cfc and the last application.cfc passed will make that decision.
So a setting unique to a request inside the application.cfc that is perhaps not unique to a request?
in practice most applications i see only pass one application.cfc in a single request and if there are more than one, i can live with "the last decides", what do you think?

We do the best to add support for as much as possible to the application.cfc, but the question is, what miss you most in the application.cfc?

what you think about a setting like
this.singelton=true;
// or
this.loadingOnce=true;
if set to true, the application.cfc is only loaded once and not new with every request (what is a speed improvement)?

Micha

Chris Blackwell

unread,
Nov 1, 2013, 5:56:59 AM11/1/13
to railo
+1 for making Application.cfc a singleton. 

That would mean that your application could have instance data that didn't have to be exposed to all and sundry in the application scope.  Would likely break lots of FW/1 apps that don't use local scoping inside their views.




--
Did you find this reply useful? Help the Railo community and add it to the Railo Server wiki at https://github.com/getrailo/railo/wiki
---
You received this message because you are subscribed to the Google Groups "Railo" group.
To view this discussion on the web visit https://groups.google.com/d/msgid/railo/CAJVB4jec%3DXQGYRQLMuAb5NSqDL5o5rNAO7N3g0BoC4xRWLdbEg%40mail.gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.

Nando Breiter

unread,
Nov 1, 2013, 6:26:00 AM11/1/13
to ra...@googlegroups.com
I know it would depend on the application.cfc file, but what range of speed improvement would the this.singleton=true setting typically achieve? 

Chris, can you explain why this change might break FW/1 apps that don't use local scoping inside views?





Aria Media Sagl
Via Rompada 40
6987 Caslano
Switzerland

+41 (0)91 600 9601
+41 (0)76 303 4477 cell
skype: ariamedia


Chris Blackwell

unread,
Nov 1, 2013, 6:49:56 AM11/1/13
to railo
@Nando

When FW/1 renders a view framework.cfc cfincludes it and saves the content (see here)
So in your view if you write code like this

<cfset somevar = true /> 

Then this actually ends up setting variables.somevar in the current instance of your Application.cfc.  Usually this isn't an issue as the App.cfc is instantiated fresh on every request so the variables scope is clean.

So now imagine if every variable you set in a view ends up persisted in your Application.cfc variable scope.. things will go horribly wrong.

The official way to avoid this is to local scope your view variables, 

<cfset local.somevar = true />

this make the variable local to the function that included it and avoids the pollution, but how many people do that.. not many i bet.  However you can still get cross-view variable leakage within the same request.  

This has been something that i've never liked, and was one of the reasons I use my own framework (cyril), that extends FW/1, but uses a view Renderer component to isolate views from the Application.cfc


All that said, I'm strongly in favor of a singleton Application.cfc, even if it provides zero performance enhancements in itself, it will have performance benefits when it comes to things like calculating dynamic mappings, or configs only once.

For development though, there would need to be a way to force Railo to reload the application.  We have applicationStop() already, so maybe an applicationReload() function ?

Chris





Andrew Penhorwood

unread,
Nov 1, 2013, 7:33:51 AM11/1/13
to ra...@googlegroups.com
I am +1 on being able to set things in Application.cfc.  The singleton idea I will have to think about and see how that would effect my framework.

Andrew Penhorwood


Chris Blackwell

unread,
Nov 1, 2013, 8:40:11 AM11/1/13
to railo

On 1 November 2013 11:33, Andrew Penhorwood <and...@coldbits.com> wrote:
 The singleton idea I will have to think about and see how that would effect my framework.

As with all Railo enhancements, it wouldn't effect you unless you chose to switch it on.

Nando Breiter

unread,
Nov 1, 2013, 9:16:11 AM11/1/13
to ra...@googlegroups.com
@Chris

That's what I assumed. 

What I don't particularly like about the scenario you illustrated is that it seems to create another area, in addition to local function variables, where leakage can occur that developers would need to watch out for. I assume that then anything inadvertently set to variables scope in the Application.cfc methods that are fired per request or per session would also be susceptible to leaks? I can imagine security holes opening whereby visitors who are not logged in suddenly have access to secured areas of an application, for instance, if someone turns this option on and doesn't carefully review, or understand, how it affects their application, particularly in that they would not catch this in local testing.


Aria Media Sagl
Via Rompada 40
6987 Caslano
Switzerland

+41 (0)91 600 9601
+41 (0)76 303 4477 cell
skype: ariamedia


Chris Blackwell

unread,
Nov 1, 2013, 10:33:56 AM11/1/13
to railo
On 1 November 2013 13:16, Nando Breiter <na...@aria-media.com> wrote:
I assume that then anything inadvertently set to variables scope in the Application.cfc methods that are fired per request or per session would also be susceptible to leaks?

No more so than is already the case in singleton controllers or services and Railo already provides a way to limit unscoped variable leakage (Settings > Scope > Local Scope Mode)


Bruce Kirkpatrick

unread,
Nov 1, 2013, 10:42:05 AM11/1/13
to ra...@googlegroups.com
I definitely want the singleton feature on application.cfc - I recently mentioned this on the other thread that was talking about Mark Drew's datasource video here: https://groups.google.com/d/msg/railo/JyjOHALRkh8/3cQwvHNAq8AJ

If you make application.cfc big, then you definitely don't want it to run all the time.  I think this.name can run on each request so it lets the right persistent container, but then all settings should be defined in onApplicationStart and preserved thanks to the singleton option causing it to be persistent.   I'd prefer this even if it causes thread safety issues, because I can fix threading problems, but I can't improve performance of Application.cfc right now.   If you really wanted to make it easy for us, you'd have a function we can call the set the "persistent application settings" by passing in a struct that takes effect immediately for the current request.  Then we wouldn't have to worry about thread safety issues inside onRequestStart / onRequestEnd and could be lazy like it is now.

It doesn't matter what the actual speed improvement is, it just doesn't make sense to be executing multiple times that is meant to be run once.  If your app relies on the dynamic nature of application.cfc settings, you could always change that later to take advantage of the speed boost.

I definitely put cfsetting requesttimeout in specific sections of my app, and it would be wrong to be set in application.cfc.

Matt Quackenbush

unread,
Nov 1, 2013, 10:50:03 AM11/1/13
to ra...@googlegroups.com
I'm kinda late to the party, but I'll just note that having App.cfc a singleton would break EVERY FW/1 application. FW/1 leverages (i.e. relies on) the fact that App.cfc is new and fresh on every request. As long as the default behavior remains the same as it is now, things should be just fine, but it is important to note that some frameworks/apps rely on the existing behavior (since it's been that way ever since App.cfc was introduced).

I think my only question/concern would be with regard to the on*Start|End() methods. Would they still behave in the same way if App.cfc was a singleton? My assumption is yes, but just want to confirm that.




Bruce Kirkpatrick

unread,
Nov 1, 2013, 10:52:02 AM11/1/13
to ra...@googlegroups.com
However, if you took the approach of making a function such as setApplicationSettings(required struct);, then you could just build your app so that it runs that again when you have a CGI parameter passed to the app, or other events that are application specific.   I already do this for firing onApplicationStart through the url when it matches my ip and that works fine.     

If you don't know, you can already redefine the application "this" scope in the middle of onRequestStart, it just isn't persistent on the next request, so you have to be careful.  For example, you can make a new mapping or datasource inside onRequestStart now with railo.    If application.cfc was persistent, you'd just be updating the "this" scope in onRequestStart when you need to reset it and it would be saved for future requests.   You have to be careful about thread-safety though, which is why I'd rather have a function for this so that all requests lock whenever the settings are being changed.  

Bruce Kirkpatrick

unread,
Nov 1, 2013, 10:59:08 AM11/1/13
to ra...@googlegroups.com
like if you define a datasource incrementally like this, you might break other requests that use it because some of the parameters may getting updated and another thread would read halfway updated struct and fail immediately:

this.datasources.zcore={
class:'org.gjt.mm.mysql.Driver'
};
this.datasources.zcore.username:'root';
this.datasources.zcore.password:"pass";

Defining it all with the shorthand syntax as one struct declaration fixes that thread-safety problem of course, but a developer has to be careful.  This is just a single example of how a persistent application.cfc could be harder to program then giving us a function that sets an internal data structure without making application.cfc a unique singleton.

Bruce Kirkpatrick

unread,
Nov 1, 2013, 11:06:56 AM11/1/13
to ra...@googlegroups.com
My idea would look like this in code:
<cfcomponent>
<cffunction name="onApplicationStart">
<cfscript>
var ts={
mappings: {
"/map":"/path/to/map"
},
SessionManagement = true,
        SetClientCookies = false
}
setApplicationSettings(ts); // all settings are set atomically - forcing thread safe values.
</cfscript>
</cffunction>
<cfscript>
setApplicationName("myApp");
</cfscript>
</cfcomponent>

You could also give us a getApplicationSettings() functions that returns a deep copy of the settings, so we could just make incremental changes, and then pass it back to setApplicationSettings().   This would let you run more complex (slow) validation on the configuration passed in so that there is a guarantee it is correctly programmed.   You could start adding more complex application.cfc railo configuration features that take time you can't usually waste on individual requests.  Like datasource connections could be verified, mail server connection verified, etc.

Nando Breiter

unread,
Nov 1, 2013, 11:33:44 AM11/1/13
to ra...@googlegroups.com

I think my only question/concern would be with regard to the on*Start|End() methods. Would they still behave in the same way if App.cfc was a singleton? My assumption is yes, but just want to confirm that.

 
Expanding on this ... developers should be able to set any variable currently in Application.cfc's this scope on every request if needed. I think that is what Micha was driving at when he talked about placing all settings in functions? 

As an example, I have an app where this.name is set dependent on the domain name - so that application scoped variables are seperated per domain rather than per code base. I would expect this is a common use case ...

Michael Offner

unread,
Nov 1, 2013, 11:40:30 AM11/1/13
to ra...@googlegroups.com
first of all, the methods onApplicationStart , onSessionStart are executed thread safe for simple reason.
let say you are starting the server and you are getting 10 concurrent request, one of this requests executes the "onApplicationStart" and all the other have to wait until he is done,  when they all have the same "cfid", after that one of them is executing the "onSessionStart" and all the others have to wait again, after that all of them are executing the "onRequestStart" method.
Al this is happening to make sure that the "onApplicationStart/onSessionStart" are executed only once for a new application/session scope and that the listener function are executed in the right order.
Last time i checked ACF, they had this thread safety not in place and it is possible that a "onApplicationStart/onSessionStart" is executed twice for a new scope or you reach "onRequestStart" before the others was executed...

i got a liitle offtopic, sorry
In railo the tag <cfapplication> still support every setting possible with the application.cfc, we treat that tag not as predecessors of the application.cfc, no with the attribute "action" we have give that tag a new meaning.
you can now do something like this
<cfapplication action="update" mappings="#{'/test':somePath}#">
i do this a lot in my cfml code, that is really handy.
so in your case you could do:


<cffunction name="onApplicationStart">
<cfapplication action="update" SetClientCookies = false SessionManagement=true mappings="#{"/map":"/path/to/map"}#">
</cffunction>










2013/11/1 Bruce Kirkpatrick <br...@farbeyondcode.com>

--
Did you find this reply useful? Help the Railo community and add it to the Railo Server wiki at https://github.com/getrailo/railo/wiki
---
You received this message because you are subscribed to the Google Groups "Railo" group.

For more options, visit https://groups.google.com/groups/opt_out.



--
/micha

Michael Offner CTO Railo Technologies GmbH

Bruce Kirkpatrick

unread,
Nov 1, 2013, 12:23:38 PM11/1/13
to ra...@googlegroups.com
I had no idea that <cfapplication> had these exclusive features.  I see it in the railo docs now. 

onApplicationStart is not my concern, but that's great Railo locks it better for you.  

I'm more worried about onRequestStart and onRequest thread safety when application.cfc is persistent.

OnRequest does a <cfinclude template="">.  If you have variables in your .cfm that use the variables scope, then every thing in the onRequest would become persistent across all of the concurrent requests.  You'd have some serious thread-safety bugs resulting from the shared variables scope inside application.cfc.  You could work around this by executing your include inside a unique local CFC, but the app may depend on data set in onRequestStart, so you may have to inject a duplicate of those variables for it to work.

onRequestCFC, would be a bit easier to deal with since CFC's have their own scopes.

OnRequestStart/End probably wouldn't be as hard to fix for thread-safety, but they probably wouldn't work immediately for most people.

I already stopped using onRequest (cfm files) for my entire core framework, but my older projects use it a lot without any concern for variable scoping.  I'd have to update them or put them in a separate context.  It would be impossible to use persistent application.cfc unless everyone rewrites a lot of code or puts <cflock name="uniqueNameForOnRequest" type="exclusive"> in onRequest.

Bruce Kirkpatrick

unread,
Nov 1, 2013, 12:38:00 PM11/1/13
to ra...@googlegroups.com
After a short break, I realized that one could just create another CFC that has all the same events as Application.cfc.  You'd just have to make a local instance of this CFC on each request, and move all your existing non-thread-safe code to that and call the events on the per-request cfc.   It wouldn't matter that application.cfc is persistent.   That should fix that FW/1 issues everyone has mentioned and the things I mentioned.

Bruce Kirkpatrick

unread,
Nov 1, 2013, 12:40:36 PM11/1/13
to ra...@googlegroups.com
Code example:

<cfcomponent>
<cfscript>
request.myApplicationCFCHack=createobject("component", "legacyApplicationCFCEmulator");
</cfscript>
<cffunction name="onRequestStart">
<cfscript>
request.myApplicationCFCHack.onRequestStart();
</cfscript>
</cffunction>
</cfcomponent>

Igal @ getRailo.org

unread,
Nov 1, 2013, 12:43:53 PM11/1/13
to ra...@googlegroups.com
I'm not sure what you're trying to do, but in most cases it'd make more sense to extend "legacyApplicationCFCEmulator"

e.g. Application.cfc:

component extends=legacyApplicationCFCEmulator {

    function onRequestStart(args) {
   
        super.onRequestStart(args);        // this calls legacyApplicationCFCEmulator's method

        // do other stuff
--
Did you find this reply useful? Help the Railo community and add it to the Railo Server wiki at https://github.com/getrailo/railo/wiki
---
You received this message because you are subscribed to the Google Groups "Railo" group.

For more options, visit https://groups.google.com/groups/opt_out.

-- 
Igal Sapir
Railo Core Developer
http://getRailo.org/

Bruce Kirkpatrick

unread,
Nov 1, 2013, 12:48:37 PM11/1/13
to ra...@googlegroups.com
No, you can't do that because application.cfc is persistent in this imaginary future version of Railo.  onRequestStart would be sharing the "this" and "variables" scope which is why I create the object in request scope so it's detached from local or variables scope.

Michael Offner

unread,
Nov 3, 2013, 9:29:20 AM11/3/13
to ra...@googlegroups.com
You have a very good point here, so even the application.cfc is a singleton, the variable scope has to be unique for every single request.

Micha

For more options, visit https://groups.google.com/groups/opt_out.


--

Charles Robertson

unread,
Sep 4, 2016, 12:11:52 PM9/4/16
to Railo, mic...@getrailo.com
This is crazy. The whole point of the onRequest... methods in the application.cfc, is that they are executed once per page request. Surely, you are not talking about persisting request variables, or have I completely misunderstood what you are proposing?
Reply all
Reply to author
Forward
0 new messages