The Dopefly Tech Blog
<< The Dopefly Tech Blog Main page
Post A Comment!
Why Client Variables are Flawed
posted under category: ColdFusion on July 7, 2005 at 11:53 am by MrNate
Client variables in ColdFusion are flawed. Inherently from the start, they're no good to use. First off, where are you going to store the data?
Registry: Don't do this. Especially if you intend on having users on your web site. This expands your registry and will make your whole server slow.
Cookie: Don't do this (see 6.3). Limitations in browser cookies keep you from storing large amounts of data. Maxing out browser cookies can have (very!) unforeseen consequences. This also will increase your network traffic and bandwidth.
Database: Don't do this. Constant updates and heavy traffic will kill your database (and thus cf) servers. Come on people, there are better ways of storing data in the database.
A couple other annoyances and pet peeves of mine are:
- All options are server-wide, it would be cool to have different options for each application
- For my database's sake, select the data once and only insert/update them at the end of the session
- Need more storage options, how about using files or a proprietary client variable server (aka state server)
I think there's still something to be said for dynamically created persistent data that can be tied to unknown visitors. Too often we use a cheap cookie (watch those limits), or go overboard and change our database schema to add a temporary property, but a better structure from the start would solve that.
What we need is a more intelligent client scope that will fix the insanity. We need more control over the little things, even over the inserts and updates in the database. It's got to be built with open source CFCs or expose itself with extendable java. Mix it with CFMX 7's new Application.cfc event handlers (especially onSessionEnd) and we could have something really useful.
There are only a couple ways of going about getting what we want. We either build it ourselves or we beg the CF developers and hope for the best. My money is on doing it myself. I'll be thinking more about this, so expect to see more posts about it in the future.
On Jul 7, 2005 at 9:59 AM ike (info who loves turnkey.to) said:
Do you stand by your claim of client variables being bad for the database server even when "Disable global client variable updates" is checked in the client variable configuration? This setting dramatically reduces the number of times the client variable store is queried. Or so I've heard from people who've had success solving some problems by using the setting.
On Jul 7, 2005 at 10:17 AM Tom Cornilliac (tomcornilliac has underestimated gmail.com) said:
"All options are server-wide, it would be cool to have different options for each application"
You can so long as you run Enterprise and use Multiple Instances.
On Jul 7, 2005 at 10:18 AM Nathan Strutz (http://www.dopefly.com) said:
While disabling global client variable updates will help dabase client storage out a lot, the way CF's built-in client storage works (at least with my SQL Server) is pretty flawed, calling sp_prepare/sp_execute/sp_unprepare on every interaction. Ideally, it would create a stored proc or use a regular query with bind parameters to do what it needs. Additionally, I'd like the ability to save this data on the server until the end of my session, then commit the data to the server onSessionEnd.
Under heavy load, even client variables with updates disabled will cause stability and growth problems (though there are fairly simple ways of getting around them)
On Jul 7, 2005 at 10:22 AM Nathan Strutz (http://www.dopefly.com) said:
That's a good point, and works fairly well but will cost you up to $4700 extra per server, not to mention the increased memory consumption by running multiple CF servers.
On Jul 7, 2005 at 12:18 PM Devin (devin, by way of shinynet.com) said:
I've never had any of the problems you speak of with client variables. I understand that those problems could happen. But they way you speak, we shouldn't be using cf at all... or any language.
My point is, they're not a bad thing if you use them wisely and consider the implications of it... as is true with anything.
On Jul 7, 2005 at 1:45 PM Nathan Strutz (http://www.dopefly.com) said:
My guess is you don't have any high volume production CF servers, or you don't manage your CF servers (or you don't use client vars :). As for not using any language at all, that's probably true. Servers don't crash if there's no software on them. I'm all for it!
You're right though, implimenting any solution requires considering what it will do. The fact is most people don't realize what client vars will do. That's the reason of this post. Thanks.
On Jul 7, 2005 at 4:00 PM HKS (haikal at the ever popular freeshell.org) said:
Isn't clientvars just a poor man's substitute for the Session scope? You can stick CFCs in session, and you won't have to worry about traffic, or size restrictions because it's your server anyway?
On Jul 7, 2005 at 5:49 PM Steve Nelson (m sends love to secretagents.com) said:
How much volume are you talking about? I've run sites in the past with client variables that got hundreds of thousands of hits a day. Client variables in a SQL server database with clustered CF servers didn't cause any problems. Having them in a central DB meant that if any of the cf servers in the cluster went down the users never knew. Maybe i'm just an old school CFer, but all this doomsayer talk about client variables seems like overkill to me.
On Jul 7, 2005 at 6:29 PM Barney (http://www.barneyb.com/) said:
You're missing two very important things about client variables, and no comments have caught them yet either.
First, client variables stored in the database are accessible across load balanced clusters without needing to use session replication. That's one very substantial benefit over session variables, and the reson that reading them once per session won't work. If you want to use session variables, use them, and then use a real DB schema for any persistant stuff you want cross-session. The point of client variables is to not use the session scope at all.
Second, client variables are read at the beginning of the request, and written at the end. That means you HAVE to single thread access for each given client, or you'll run into problems. This isn't usually much of an issue if you've got snappy pages and no frames, but if you're using frames, have long running pages, or are doing any kind of remoting, it can be a big problem.
On Jul 7, 2005 at 8:05 PM Scott Stroz (scott who wouldn't be caught dead at boyzoid.com) said:
I actually have to use (and work on) an application that will return over 900 (that's not a typo, 900) client variables if you do
On Jul 7, 2005 at 8:18 PM Steve Nelson (m who can't believe it's not secretagents.com) said:
But Barney aren't they only written if they're changed? If global updates are turned off and all you're doing is grabbing a client variable, that's a single select statement. How is that any different than any DB select and update statement? It's not like the implementation is anything revolutionary. If you need persistant data for the purpose of load balanced servers, how would you do it any differently than client variables currently work?
On Jul 8, 2005 at 1:41 AM Julian (http://simplicityweb.co.uk) said:
Steve, No experience myself, but I believe you can do session sharing between clustered servers with CFMX Enterprise (J2EE). For me though client vars still have the advantage that they don't get zapped if you have to restart the CF service for any reason, ie users aren't forced to log in again.
On Jul 8, 2005 at 5:02 AM Steve Nelson (m who spends every waking moment visiting secretagents.com) said:
Julian, you can share session scope on j2ee. I don't know how to inner workings of it work, but just think about. There are only a small handful of ways it could work. Either 1) it writes the data to disk in a central location and all servers read from that location 2) it writes the data to memory in a central location and all servers read from that location 3) it writes the data to memory on every server
Option 1 is really no different than client variables in theory at least. It's hard to compete with the speed and scalability of a DBMS system.
Option 2 has the flaw of the central IMDB (in memory database) going down and losing all of the data, so in this situation you'd need to write to the disk again. Now if MM built an IMDB, which they may have, i'd be impressed.
Option 3 is most likely how it works. Only because this is how someone explained to me how j2ee session variables work. The biggest flaw i see is keeping the servers in sync, when a variable is written it can either be immediately sent to every server in the cluster and be instantly in sync or sent on a scheduled basis. If it's immediate, that's quite a bit of network traffic and CPU wasting, but not terrible. If it's scheduled, then there is a decent possibility of being out of sync when a server goes down, creating a bad experience for the user.
Anyone know how j2ee session vars actually work?
On Jul 8, 2005 at 7:03 AM Jeremy Bruck (jeremy at the ever famous flexingcfmx.com) said:
We do run a clustered site (3 servers) and we have used client variables for our "users information". We create a structure upon login, convert it to a wddx packet, and store the wddx packet in the client variable (database).
We do have a high volume site (about 25,000 unique visitors/day) and we have never had a problem using client variables. Their have been some bugs in CFMX along the way with client variables -- deleting them for instance causing issues, but that has been patched. We have used this methodology (wddx client vars) for the past 3 years.
We have debated using session replication (J2EE), but this way is soo easy and once we are loadbalanced overseas (multiple hosting location) I think the client variables will be even easier to manage versus J2EE session replication.
And yes if a page has 10 references to the client variable, it doesn't hit the database 10 times -- just once for the entire "page/request".
On Jul 8, 2005 at 11:21 AM Charles Randall (crandall, visiting us from recruitmax.com) said:
Steve, your hunch is correct. J2EE session variables are replicated across application servers in a cluster. This architecture scales well on any decent infrastructure, and does not generate significant overhead.Synchronization is indeed the weakness of this design, but is usually handled well by the leading J2EE servers on the market today.
Now about those Client variables...
MrNate's analysis of the problems associated with Client variables is quite good. However, the risks of using an ENTERPRISE-CLASS database server for client variables are certainly tolerable.
I am sure we would all love to have more granular control of Client variable storage. ***At the very least, the ability to accurately schedule client variable deletion from the database***
For those interested in client variable storage alternatives, MS State Server can be used with BlueDragon.NET. For more information about this option, visit http://www.newatlanta.com/
On Jul 8, 2005 at 12:26 PM Nathan Strutz (http://www.dopefly.com) said:
From what I read, ASP.NET doesn't have an equivalent to client vars. The state server (and sql server options) are for straight session data, where as client vars are typically available for weeks or months.
On Jul 16, 2005 at 1:13 PM Joe (joeblackde at the endearing hotmail.com) said:
Here's an idea.
How about writing a cfc that retrieves all the client variables and saves them to VARIABLES or THIS. Instantiate that cfc when the user logs in. On session end, write the variables to the database.
I havn't tried that, but it seems like it may help. Feel free to correct me if I'm wrong. I'm still not fully aware of how much ram instantiating a cfc takes up.
On Jul 18, 2005 at 9:52 AM Nathan Strutz (http://www.dopefly.com) said:
Joe, you're right on the money. That's probably the easiest way to solve my biggest beef with the old client scope. It wouldn't take much tuning to change client.* to session.client.*, at least on most sites. Still, it doesn't solve everything, but it would be a great quick-fix.
Post A Comment!