Content feed Comments Feed

Managed Mayhem

More Than 99 Billion Cats Herded

Archive for the ‘Cold Fusion’ Category

Coldfusion Is Not Scalable

Posted by Jim Rising On February - 11 - 2010

Even after 12 years of developing enterprise ColdFusion applications, I’m still amazed that I hear statements like this. I recently left a job where I helped to build a highly scalable application for the financial industry using CF. Our team used EXTjs, MySql, and Railo as the CF parser. I am still ‘invested’ in this project, and so I was talking with the COO yesterday and he mentioned that there was another developer they were talking with who said … ‘Coldfusion is not scalable’. No explanation given… just that it wasn’t scalable. I was actually a bit irritated, and so I asked the COO to just ask him ‘Why?’.

The enterprise versions of Adobe Coldfusion, Railo, and OpenBlueDragon all come with built in clustering using J2EE session management. Adobe’s version 9 comes with Hibernate support built-in… and Railo is soon to follow suit. Companies like Etrade, NASA, GoldLeaf, Caterpillar… all use ColdFusion. All of the parsers support enterprise DBMs like Oracle, MSSQL, Postgres, and MySql. All of the parsers come with a form of memory caching.

My only ‘guess’ is that he’s possibly talking about it not being financially scalable. Perhaps he doesn’t know that there are now 3 different open source CF parsers available? (openBlueDragon, Railo, Smith) Part of the reason why MySpace moved away from Coldfusion was primarily a licensing issue. Adobe ColdFusion licenses are not cheap, but they are justifiable. Even if he was talking about a financial scalability issue due to licensing… it’s just something that you build into your business model on the front end to make sure that you have the money available either through investment or financing.

Either way, we had already addressed the financial scalability issue by choosing Railo as the parser, and I built in my own clustered session management using in memory sessions backed up by persistent sessions in MySql. Combined with sticky sessions in Apache, a front end load balancer and simple MySql replication, and you have a pretty solid HA setup. It’s not J2EE, but it worked. We were also planning on rolling it into the cloud when we released it into production, and so those MySql servers would have had up to 32GB of RAM and 8 processor cores available to each of them (vertical scalability), with the web servers being horizontally scalable as much as needed. Down the road we could have always moved to MySql Clustering when it was actually needed, giving us true horizontal scalability. I’d say that’s pretty scalable.

My point is that it really is not the language that makes an application scalable. Certain tools can make it easier (Enterprise CF vs. Standard) … but it is really dependent on how the application is designed in the first place. Most of the HA scalability issues can (and should) be mitigated to the network and operating system layers rather than handling them within the application layer anyhow. Saying ‘Coldfusion is not scalable’ seems to me to be a real misunderstanding of how highly available applications are really built.

Convention over Configuration

Posted by Jim Rising On February - 10 - 2010

I’m noticing a trend… and I’m liking it. I’ve been working with cakePHP … and they have a wonderful way of causing you to want to name things a certain way so that you don’t have to fiddle with a bunch of configuration files… Coldbox (which I love!) has the same thinking behind it… but still has a nasty mess of xml files that you wind up needing to hoark with.

In CakePHP … your database tables, models, controllers and views are all linked by the naming convention that is used…

  • Database table: “dogs”
  • Model class: “Dog”, found at /app/models/dog.php
  • Controller class: “DogsController”, found at /app/controllers/dogs_controller.php
  • View template, found at /app/views/dogs/index.ctp

It even has a cool little ‘inflector’ class that will take a string and pluralize it for you if you need help:

Example: Inflector::pluralize('dog') returns “dogs”.

Neat.

I remember what a pain Fusebox used to be … one of my biggest complaints about the framework was that it was so laden with XML configuration files everywhere!

Coldbox still has quite a bit of setup you need to go through using XML, but similar to the way that Fusebox has transitioned over time (I started with Fusebox at version 2!)… all of your models, views, and controllers (handlers) are CFC object based rather than dealing primarily in XML.

MAMP and Cold Fusion Tutorial

Posted by Jim Rising On February - 10 - 2010

I recently re-installed OSX on my mbp … and decided to look into a more integrated approach for my development environment. Since I’m developing in PHP as well as CF, I opted to pickup MAMP, which is a packaged lamp-ish type stack installer and configuration manager for Apache, MySql, and PHP on Mac. There is a free version, but I decided to get Mamp-Pro because I like using virtual hosts, and it’s such a good product that it needs to be supported.

Mike Jones has a great video tutorial for CF8 that helped me get CF9 up and running under MAMP.

Factory Method

Posted by admin On May - 8 - 2009

Factory methods are responsible for manufacturing objects.

From ‘Gang of Four’:

‘Frameworks use abstract classes to define and maintain relationships between objects. A framework is often responsible for creating these objects as well’

Coldspring as a framework has an excellent implementation of the Factory Method pattern.

Example:

Let’s say I am building an application that has ‘CDs’ as objects.

If I am using a Service / Gateway / DAO pattern in my application… (I know that many folks rail against the 5:1 approach, but let’s just say for sake of argument that transfer is not a good fit for this application.), I have quite a bit of code to write just to get to a point where all of my required objects are instantiated:

<cfset datasource="library">
 
<cfset cdBean = createObject("component", "extensions.com.jimrising.cd.cd").init(title: "Joshua Tree", artist: "U2")>
<cfset cdDAO = createObject("component", "extensions.com.jimrising.cd.cdDAO").init(dsn: #datasource#)>
<cfset cdGateway = createObject("component", "extensions.com.jimrising.cd.cdGateway").init(dsn: #datasource#)>
<cfset cdService = createObject("component", "extensions.com.jimrising.cd.cdService").init(cdDAO: cdDAO, cdGateway: cdGateway)>

Note that the ‘cdService’ depends on the injection of the cdGateway and cdDAO. Coldspring handles this dependency injection nicely as well.

In order for me to create a new ‘cd’, and then save it to the database:

<cfset cdService.save(cdBean)>

The issue is one of persistence. In order for me to use these objects throughout my application, without the Factory Method, I would need to instantiate them each time I needed them. Using the Factory Method and a little setup within Coldspring, these objects persist and I’m able to access them through the factory, without needing to know all of the dependencies or subclasses:

<cfset application.serviceFactory.cdBean.init(title: "Joshua Tree", artist: "U2")>
<cfset application.serviceFactory.cdService.save(cdBean)>

Note that the DAO, Service, and Bean have already been instantiated, and so saving a new ‘cd’ object to the database (from anywhere within your application) is a simple matter of building the bean and saving it through the service within the serviceFactory.

Here is what the XML configuration (services.xml) looks like for ColdSpring:

<beans>
    <bean id="cdGateway" class="extensions.com.jimrising.cd.cdGateway">
        <constructor-arg name="dsn"><value>${dsn}</value></constructor-arg>
    </bean>
    <bean id="cdDAO" class="extensions.com.jimrising.cd.cdDAO"> 
        <constructor-arg name="dsn"><value>${dsn}</value></constructor-arg> 
       </bean>
    <bean id="cdService" class="extensions.com.jimrising.cd.cdService">
        <constructor-arg name="cdDAO"><ref bean="cdDAO" /></constructor-arg>
        <constructor-arg name="cdGateway"><ref bean="cdGateway" /></constructor-arg>
    </bean>
 
    <bean id="cdBean" class="extensions.com.jimrising.cd.cd" />
</beans>

And the simple one time instantiation of the serviceFactory within your application.cfc onRequestStart() method:

        <cfset application.defaultProperties.dsn = "myDsn"/>
        <cfset application.serviceFactory = createObject('component','coldspring.beans.DefaultXmlBeanFactory').init(structnew(),application.defaultProperties)/>
        <cfset application.serviceDefinitionLocation = expandPath('/config/services.xml')>
        <cfset application.serviceFactory.loadBeansFromXmlFile(application.serviceDefinitionLocation)/>

I was working last night on an application built on the following platform:

Railo 3.0
Centos 5.1
Apache2
MySql 5

The application isn’t doing anything crazy… just some queries and some file uploads. I kept getting this though:

Communications link failure due to underlying exception: ** BEGIN NESTED EXCEPTION ** java.io.EOFException STACKTRACE: java.io.EOFException at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1956) at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2368) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2867) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1616) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1708) at com.mysql.jdbc.Connection.execSQL(Connection.java:3249) at com.mysql.jdbc.Connection.execSQL(Connection.java:3178) at com.mysql.jdbc.Statement.execute(Statement.java:711) at railo.runtime.type.QueryImpl.<init>(QueryImpl.java:175) at railo.runtime.tag.Query.execute(Query.java:406) at railo.runtime.tag.Query.doEndTag(Query.java:340) at …

It took me a bit, but I finally figured out how to handle it…

In /etc/my.cnf
Adjust the ‘wait_timeout’ directive to a reasonably high number. It is in seconds… and default is set to 30 seconds.

wait_timeout = 1200

The second thing you want to do is make sure that within the Railo Web Administrator’s datasource dialog, your ‘Connection timeout (in minutes)’ is set to a number that is significantly lower than MySql’s ‘wait_timeout’. What this does is it makes sure that Railo properly closes inactive database connections before MySql does.

Managing Threads in Coldfusion

Posted by Jim Rising On May - 6 - 2009

[this is actually an older article from my previous blog, just moving it to my mm blog] …

cf_appicon

I started looking at <cfthread> today, and realized that it really does not have any sort of management facility built into it. while you can view / manage threads from within the server monitor…

1) you can’t get a status for a thread except from the calling page, or from another thread that was called from that page. this presents a problem if you have long running threads, or if you have other parts of your application that rely on thread status.

2) if there is an error that was generated during a thread process, again … you can access this at the page level, or from another thread, but there really isn’t anything that will help you to manage this within your application logic, say if you wanted to fire a thread again later.

Matt and I discussed an approach that could work well for managing these two things that are missing natively in cfthread, and act as a good foundation for further thread management. Keep in mind that this article really only consists of some raw ideas with pseudocode at this point. I’ll get around to writing the actual components later, and i’m sure it will develop into something much different from the ideas on this page.

The concept is based on two components that manipulate a server struct and act as a wrapper for cfthread:

the server struct consists of the following:

server.instance.threadName
server.instance.initTimeStamp
server.instance.startTimeStamp
server.instance.endTimeStamp
server.instance.elapsedTime
server.instance.function (join, run, sleep, terminate)
server.instance.priority
server.instance.object
server.instance.method
server.instance.argList
server.instance.status
server.instance.error

threadManager.cfc
This is the thread manager responsible for creating new threads, cleaning up old threads, and contains the getters / setters for thread status and errors.

thread.cfc
This is the thread object that acts as a container for thread processes. It builds a thread using <cfthread>, and creates a structure in the server scope containing the name of the thread, timestamp when it was created, current thread status, and any errors that occur.

myThread = thread.new(run, object.method, argumentList);

what this would do is create a new ‘run thread’ using the object.method(), given a name | value list of arguments. it would return the name of the thread as a UUID, and would add the thread instance to the server.instance struct. note that we’re passing in a list of arguments and values not for thread.new, but for the object.method.

newThread.exec(myThread);

this would execute the thread created previously, updating server.instance.startTimeStamp and server.instance.status in the server.instance struct. if the thread runs into any try/catch … this would be updated to server.instance.error. once the thread is completed, server.instance.status would be updated, as well as server.instance.endTimeStamp. all we’re doing here is passing the myThread object into newThread.exec, and then wrapping the object.method(argumentList); within <cfthread>

About Us

"Managed Mayhem" is a software project development and management blog maintained by Jim Rising. Jim Rising is an Adobe Cold Fusion developer who lives in Murfreesboro, Tennessee with his wife Melissa, their son 'Haven', cat ‘Rusty’, and dog ‘Güenther’. He currently freelances from home.