Link to home
Start Free TrialLog in
Avatar of Garbonzo_Horowitz
Garbonzo_HorowitzFlag for United States of America

asked on

Placing Objects in Application Scope in a Web App

Several ColdFusion frameworks use the technique of placing objects (CFC's in coldfusion) into the Application scope. Specifically within Application.cfc.  I would like to know what is actually happening when this occurs. I understand this is how to create a Singleton Pattern but in the back of my mind I always thought of application variables as constants instead of variables and that they should be used to only to tie information to the whole application. For example a datasource name. The datasource name XYZ will always be the same and can be used across the whole web application.

Can someone explain the reasoning and mechanics of placing objects in the Application scope? I'm using ColdFusion but this could be done in any language.
SOLUTION
Avatar of gdemaria
gdemaria
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
(small comment ...)

I think it's primarily because of the reasons you and gd have already given:

      1. It's the closest thing CF has to constants. Anything in the app scope is
      essentially global, and available to the entire app

      2. Performance. Creating objects requires resources, so with things like dao's
      and utility components, utilizing the singleton  pattern minimizes the impact.  
      Since CF doesn't really have constants, or "statics", like in java, I think the app
      scope is the next best thing.
Avatar of Garbonzo_Horowitz

ASKER

Would it wreak havoc on memory? If the object is in application scope and being accessed by multiple users that means lot's of objects in memory throughout the life of the application???

Also, just to verify. This is data safe too right?  Like user A will never accidently get data that belongs to User B. Even if there is instance data.
> If the object is in application scope and being accessed by multiple users that means lot's of objects in memory throughout the life of the application

This is very efficient because there is only one occurrence of the function used by everyone.

> Like user A will never accidently get data that belongs to User B. Even if there is instance data.

If you are component level variables (variables that persist within the cfc between calls), then you do not want to use application level cfc, you want to use session level instead.  Session will be specific to a user.   The difference is, when you call a function, for example, called "multiple" it takes in x and y and returns the product, nothing is stored or saved.   In another case you could have a shopping cart that you keep in memory (inside the cfc component variables).  Adding a product would update the cfc variable and persist.  In this case, you need to do session variable cfc.    In most cases, this is not the way developers tend to do this (at least not in my thinking), as its much better to store those values in the database instead of a cfc variable.
> If the object is in application scope and being accessed by multiple users that means lot's of objects in memory throughout the life of the application???

Actually it's the opposite. If you create the object in onApplicationStart, and store it in the app scope, there's only ever one copy in memory.  If however, you created the object every time a certain page loads:

        <!---- somePage.cfm --->
        <cfset variables.obj = createObject("component", "MyComponent")>
        <cfset variables.obj.doSomething(....)>

... then you're creating many instances of "MyComponent": one for every request.  If 30 simultaneous http requests come in for "somePage.cfm", you'll have 30 objects in memory, (versus only one if you're using the app scope).

Granted those 30 object's are transitory, and will drop out of memory over time. But expending all those resources to create, destroy and garbage collect the objects (not to mention the time) is really a waste. With stateless objects - you only need one copy.

(Edit) Keep mind we're only talking about the component. Any functions inside it are still going to create objects in memory ever time they're invoked - no matter how you store the parent component.  It's just a matter of how many copies of that component you have floating around in memory: one or many.

> Also, just to verify. This is data safe too right?  

It depends on the component you're loading. Typically you only load stateless components into the app scope.  In other words, component's that don't retain user specific info from one request to the next.  Utility functions, like the one gd mentioned, are a good example. They don't need to know anything about previous or future calls in order to do their job. They just use information passed in, do something with it, and exit. Example:

        <cffunction name="multiply" returntype="numeric" ...>
             <cfargument name="val1" type="numeric">
             <cfargument name="val2" type="numeric">
              <!--- always var/local scope function local variables --->
              <cfset var result = arguments.val1 * arguments.val2>
             <cfreturn result >
        </cffunction>

As long as you properly localize all function variables, "stateless" components are completely safe to store in the app scope.  "Stateful" components, like the session shopping cart gd described above, are NOT safe.
One thing I tend to forget is that variable in the application scope can be updated anytime.  My mind has trouble with that.  The variable may be getting set at application start and live for 2 days but you can update it any time you want during that 2 days.  The value stored is shared to everyone.

Example usage.  Let's say you want to rotate ads on your site.  You want to make sure that all the ads get equal hits.  You can store a marker at the application level that gets set to the first ad on application start but every ad displayed moves the marker to the next.  If you do it at the session scope you are rotating on a user level which would give more views to the the first few ads.  If you use a database to track it then you DB load plus network traffic.  A single variable store in the application scope and updated ofter runs fast and very low resources.

Another thing you can do is store a query result of the list of states so you can show a dropdown anytime without re-querying the DB.  Yes you can do that with query caching as well.

I know this isn't exactly what you were asking but it's something commonly missed and I feel that everyone above answered the actual question well.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for the expert advice.