Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Expo on Google News

SYS-CON.TV
Cloud Expo & Virtualization 2009 East
PLATINUM SPONSORS:
IBM
Smarter Business Solutions Through Dynamic Infrastructure
IBM
Smarter Insights: How the CIO Becomes a Hero Again
Microsoft
Windows Azure
GOLD SPONSORS:
Appsense
Why VDI?
CA
Maximizing the Business Value of Virtualization in Enterprise and Cloud Computing Environments
ExactTarget
Messaging in the Cloud - Email, SMS and Voice
Freedom OSS
Stairway to the Cloud
Sun
Sun's Incubation Platform: Helping Startups Serve the Enterprise
POWER PANELS:
Cloud Computing & Enterprise IT: Cost & Operational Benefits
How and Why is a Flexible IT Infrastructure the Key To the Future?
Click For 2008 West
Event Webcasts
Encapsulating Session State Management
Encapsulating Session State Management

ColdFusion developers rely on session state management and the SESSION scope extensively. But as applications grow in complexity, so do the number of SESSION variables, and the risk of overwriting or misusing them. It need not be that way; with a little work (and ColdFusion Components), SESSION use can be clean, simple, and highly organized.

When Session Data Proliferates
First, an introduction. The Web is stateless. Or put in terms that actually mean something, every request on the Web stands on its own two feet. The data received by a form submission, for example, is only available in the receiving page and not to subsequent requests. Or, user credentials specified at login are not kept until logout. And similarly, items put in a shopping cart won't still be in the cart at checkout time.

But wait a minute, those statements can't be true, can they? After all, we've all put items in shopping carts and then checked out, and we've all logged in to sites that remembered us until logout, haven't we? If the Web is stateless, how is that data maintained? That's the job of session state management, a mechanism that creates the illusion of state in a stateless world.

Data to be maintained between requests is stored on the server, along with an id that designates the client that the data belongs to. That id is sent back and forth with each and every request, so that the server can associate the maintained data and give the illusion of persistent data. In ColdFusion all this is accomplished using SESSION variables. Developers simply refer to variables like #SESSION.Firstname# and ColdFusion takes care of all the details (setting and receiving session identifiers, maintaining the SESSION data, and ensuring that the correct data is used when referring to variables with the SESSION scope).

Okay, end of introduction.

So you need to track session information, great. The first thing you do is set SESSIONMANAGEMNT="yes" in your <CFAPPLICATION> tag (which makes a lot of sense; after all, you can't use the SESSION scope without having first instructed ColdFusion to enable that functionality. Once enabled you are free to save any data within SESSION. For example, a simple variable:

<CFSET SESSION.FirstName="Ben">

or a more complex data type:

<CFSET SESSION.cart=ArrayNew(1)>

or even queries:

<CFQUERY DATASOURCE="dsn"
NAME="SESSION.profile">
SELECT *
FROM Users
WHERE user_id = #FORM.user_id#
</CFQUERY>

There is no limit to what can be stored in the SESSION scope. That's a good thing, but it's also a liability. Why? Consider the following:

  • SESSION data is available all over your application. What's to stop you from accidentally setting the same SESSION variable defined elsewhere (in code that you may not have looked at recently)?
  • Unlike simple variables that are created and used in a single page, SESSION variables by their very nature are created and used all over your application. Which means that any time a change is made to how SESSION variables are used, you run the risk of breaking code that uses those variables.
  • The more you use the SESSION scope, the more memory ColdFusion needs to store that data, and as the number of connected users increases, so does that resource usage. Without paying attention to all the data being stored in SESSION, can you be sure that you are not wasting resources?

    This is just the tip of the iceberg. The key here is that because SESSION variables are so easy to create and use, their use can quickly get out of hand unless some semblance of structure is imposed.

    The Basics of Encapsulation
    The word encapsulation is one of those terms that means lots of different things and usually ends up being misused most of the time. But at its simplest, encapsulation is a technique by which applications are separated into parts so that code need not know the inner workings of things it doesn't need to know.

    For example, stored procedures are one of the best known forms of encapsulation. A stored procedure contains one or more database instructions in the form of SQL statements, but all that is hidden from the stored procedure user who simply makes a call to obtain data or to perform some other operation. What happens within the stored procedure is not important, what is important is that it does what it's supposed to do, it just works.

    ColdFusion Custom Tags (or rather, well-written ColdFusion Custom Tags) offer another form of encapsulation. A tag is invoked to perform an operation, the details of which are concealed within the tag.

    Encapsulation thus does several things:

  • Encapsulation simplifies the creation of client code: Be it a stored procedure, a Custom Tag, or a Java object, client code need not worry about the inner workings of what is being invoked, and can concentrate on the task at hand.
  • Encapsulation makes changes safe: Encapsulated objects, like stored procedures or Custom Tags, have defined input and output, and that is all the client code ever interacts with directly. This means that code within the encapsulated object is free to change, so long as the input and output stays the same. Database schema changing, for example? That can be buried within the stored procedure.
  • Encapsulation helps resource management: When all access to an entity, for example, a database, occurs via a single entry point, it becomes possible to very effectively manage reuse, caching, and more.

    I'm using the term encapsulation a little more loosely than most object-oriented developers would like, but having said that, this is indeed what encapsulation is all about. (Note: This idea was explained in detail in CFDJ, Volume 4, issue 10.)

    ColdFusion Components and Encapsulation
    ColdFusion Components (CFCs for short), first introduced in ColdFusion MX, are a way to create reusable objects in ColdFusion. Although not objects in the purest sense, they do provide basic object functionality wrapped within the simplicity that is uniquely CFML. (Note: ColdFusion Components were introduced in detail in a two-part column that appeared in CFDJ, Volume 4, issues 6 & 7.)

    Two of the most important aspects of CFCs is that they can store data internally, and they can persist. Let me explain. Within every CFC is a special scope named THIS. THIS contains some default data, but it can also be used to store data of your own. For example, the following method accepts two arguments (first and last name) and then saves them into the THIS scope:

    <CFFUNCTION NAME="SetName"
    OUTPUT="no">
    <CFARGUMENT NAME="NameFirst"
    TYPE="string"
    REQUIRED="yes">
    <CFARGUMENT NAME="NameLast"
    TYPE="string"
    REQUIRED="yes">
    <CFSET THIS.NameFirst=ARGUMENTS.NameFirst>
    <CFSET THIS.NameLast=ARGUMENTS.NameLast>
    </CFFUNCTION>

    To invoke this method you could use the following code (assuming the previous method was saved in a file named user.cfc):

    <CFINVOKE COMPONENT="user"
    METHOD="SetName"
    NAMEFIRST="Ben"
    NAMELAST="Forta">

    This next method returns a string made up of the saved first and last name:

    <CFFUNCTION NAME="GetName"
    RETURNTYPE="string"
    OUTPUT="no">
    <CFRETURN THIS.NameFirst & " " &
    THIS.NameLast>
    </CFFUNCTION>

    So, SetName saves the name and GetName retrieves it, so the following code should save my name and return it as a string:

    <CFINVOKE COMPONENT="user"
    METHOD="SetName"
    NAMEFIRST="Ben"
    NAMELAST="Forta">
    <CFINVOKE COMPONENT="user"
    METHOD="GetName"
    RETURNVARIABLE="FullName">

    If you were to execute this code, however, you would throw an error. The SetName call will work, but GetName will complain that THIS.NameFirst and THIS.NameLast do not exist. Why? After all, they were just set in SetName?

    The problem with the above invocation is that the user component is being invoked twice, two separate invocations that have nothing to do with each other. Each <CFINVOKE> loads the component, invokes the appropriate method, and then unloads the components. So when GetName is executed there is no NameFirst and NameLast in THIS; those were in the previously invoked instance.

    The solution? Persistence. Aside from being a type of file, a CFC is a ColdFusion data type, an object. <CFINVOKE>, as used above, loads the object, uses it, and then unloads it. But those steps can be separated. Look at this example:

    <CFOBJECT COMPONENT="user"
    NAME="userObj">
    <CFINVOKE COMPONENT="#userObj#"
    METHOD="SetName"
    NAMEFIRST="Ben"
    NAMELAST="Forta">

    Here the component is being loaded as an object (which it actually is). The <CFOBJECT> instantiates (creates an instance of) the user object, but does not invoke any method. Rather, it stores the object in a named variable. <CFINVOKE> then invokes the previously loaded object; notice that the value passed to COMPONENT is the object (as opposed to the name of the CFC). Once an object is loaded it can be used multiple times, and as it is the same object being used over and over, all invocations share the same object and thus the same internal THIS scope.

    Here's a corrected version of the code to set and get the user name:

    <CFOBJECT COMPONENT="user"
    NAME="userObj">
    <CFINVOKE COMPONENT="#userObj#"
    METHOD="SetName"
    NAMEFIRST="Ben"
    NAMELAST="Forta">
    <CFINVOKE COMPONENT="#userObj#"
    METHOD="GetName"
    RETURNVARIABLE="FullName">

    <CFOBJECT> instantiates the object, SetName stores the values into THIS, and GetName returns it (possibly to be displayed).

    This can also be accomplished using object style invocation. For example, the object instantiation could be performed using:

    <CFSET userObj=CreateObject("component","user")>

    and the GetName could be executed as:

    <CFSET FullName=userObj.GetName()>]

    or used directly for display as:

    #userObj.GetName()#

    Session Encapsulation
    So, components are objects and can persist. The examples thus far loaded the object as local variables (type VARIABLES, the default variable type). But other scopes may be used too. Components may be loaded into REQUEST, for example:

    <CFOBJECT COMPONENT="user" NAME="REQUEST.userObj">

    and components may even be loaded into persistent scopes like SESSION:

    <CFSET SESSION.user=CreateObject("component", "user")>

    Which brings us back to session state management. Instead of defining and accessing all sorts of SESSION variables throughout your application, you could define just one, an object (an instantiated ColdFusion Component). If your application uses user data you may want to create a user.cfc, which would contain all user information (including obtaining information from underlying databases). To check if a user has logged in you'd use code like this:

    <CFIF NOT IsDefined("SESSION.user")>
    ... redirect to login page ...
    </CFIF>

    The login page would authenticate the user (if needed) and then create an instance of the user object in the user's SESSION scope:

    <CFOBJECT COMPONENT="user" NAME="SESSION.user">

    You may then want to initialize the object so as to populate the internal THIS with any needed information (user name, color preferences, language choices, and so on). Perhaps you'd simply pass the user id to an initialization method immediately after object creation:

    <CFSET SESSION.user.Init(user_id)>

    Init() should probably return a true or false flag (indicating whether or not the initialization was successful), and within the CFC you'll probably want each method to ensure that Init() was called before begin executed, but that is all internal to the CFC.

    What about user logout? Simple; when a user logs out you'd kill SESSION. user like this:

    <CFSET StructDelete(SESSION, "user")>

    so that on a subsequent request the login and initialization process would restart.

    With user.cfc you can do anything, so perhaps you'd have methods like these:

    • ChangePassword
    • GetLanguage
    • GetFirstName
    • GetLastName
    • GetFullName
    • GetDisplayName
    • IsMember
    • IsAdmin
    As you need new methods, you'll simply add them to the component, and the client code (your ColdFusion code that uses the component) need know nothing of the internal object workings.

    And this goes beyond user processing. Consider a shopping cart example. Shopping carts are stored in SESSION variables, but instead of storing arrays or structures or arrays of structures of whatever in SESSION and accessing them directly, you'd create a cart component. To start shopping you'd create an instance of the cart:

    <CFOBJECT COMPONENT="cart" NAME="SESSION.cart">

    When an item is to be added you'd call the appropriate method:

    <CFINVOKE COMPONENT="#SESSION.cart#"
    METHOD="AddItem"
    ITEMID="#itemid#"
    QUANTITY="#FORM.qty#">

    Other methods would update or remove items, and perhaps a list method would return a query (a ColdFusion query created within the CFC using the QueryNew() function) for displaying or processing. There is no limit to what you can do within a CFC, and your CFC code can evolve and adapt independent of any calling code.

    Conclusion
    ColdFusion Components are objects. CFCs facilitate the encapsulation of data and logic, and they can be made to persist if needed. The combination of these two features makes CFCs perfect for managing session state. With minimal work the techniques described here can be used in any application, and doing so will both simplify and improve your code.

    About Ben Forta
    Ben Forta is Adobe's Senior Technical Evangelist. In that capacity he spends a considerable amount of time talking and writing about Adobe products (with an emphasis on ColdFusion and Flex), and providing feedback to help shape the future direction of the products. By the way, if you are not yet a ColdFusion user, you should be. It is an incredible product, and is truly deserving of all the praise it has been receiving. In a prior life he was a ColdFusion customer (he wrote one of the first large high visibility web sites using the product) and was so impressed he ended up working for the company that created it (Allaire). Ben is also the author of books on ColdFusion, SQL, Windows 2000, JSP, WAP, Regular Expressions, and more. Before joining Adobe (well, Allaire actually, and then Macromedia and Allaire merged, and then Adobe bought Macromedia) he helped found a company called Car.com which provides automotive services (buy a car, sell a car, etc) over the Web. Car.com (including Stoneage) is one of the largest automotive web sites out there, was written entirely in ColdFusion, and is now owned by Auto-By-Tel.

  • In order to post a comment you need to be registered and logged in.

    Register | Sign-in

    Reader Feedback: Page 1 of 1

    Latest Cloud Developer Stories
    Swisscom, the Swiss telecom, is going into the cloud business. Its subsidiary Swisscom IT Services AG has signed up with Red Hat as a Certified Cloud Provider and launched a public cloud Infrastructure-as-a-Service (IaaS) cloud targeting enterprise-class customers primarily in ...
    Apache Deltacloud, the Red Hat-contributed ReSTful API that abstracts differences between clouds so services on any cloud can be managed – provided of course there’s a driver – has graduated from the Apache Foundation’s incubator and is now a full-fledged Top-Level Project (TLP)....
    In a surprise move on Tuesday, January 10, Oracle wheeled out its Big Data Appliance. That’s the one it said in October would be ready sometime in the first half. Only nobody believed it meant early in the first half. Heck, it’s not even clear anybody thought Oracle could make ...
    Rackspace Hosting, the service leader in cloud computing, on Thursday announced its acquisition of SharePoint911, an industry leader in SharePoint consulting, training, and "JumpStart" services within SharePoint. The unification of both companies provides capabilities to deliver ...
    CloudLinux, Inc., on Thursday released CafeFS 3, a virtualized file system for shared hosters that cages each customer within its own virtualized file system. CageFS becomes part of CloudLinux OS at no additional charge. CloudLinux OS, the only commercially-supported Linux OS m...
    Subscribe to the World's Most Powerful Newsletters
    Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
    Click to Add our RSS Feeds to the Service of Your Choice:
    Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
    myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
    Publish Your Article! Please send it to editorial(at)sys-con.com!

    Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

    SYS-CON Featured Whitepapers
    ADS BY GOOGLE

    Breaking Cloud Computing News
    As client demand for engagements increases, Revel Consulting (www.revelconsulting.com), a Kirkland, ...