Transfer ORM and memory usage

Some people - myself included - have observed runaway memory usage and apparent memory leaks with applications built with certain combinations of CFML frameworks that include Transfer ORM. We spent a lot of time tuning the JVM and looking at code and database usage in our Broadchoice Community Platform (CMS), we worked with Mike Brunt on load testing and tuning (highly recommended - if you have any performance problems, get Mike on your case!) as well as working with Mark Mandel directly on Transfer itself. All that work led to a much more stable system and we decided to just continue investigating as a background task.

[More]

How many pieces are there in the UTF-8 puzzle?

I'm blogging this partly as a reminder to myself since I always forget one piece.

  • You need to specify database tables use UTF-8.
  • You need to use setEncoding() on form and URL scope to set them to UTF-8 (in Application.cfc).
  • You need to set the output content type to UTF-8.
  • You need to set the pageEncoding to UTF-8 (on any CFML page which needs it - so you might as well set it on all of them).
  • Your datasource setup, at least for MySQL, must have useUnicode=true&characterEncoding=utf-8 in the Connection String textarea under Advanced Settings.
That last piece is the one I tend to forget when I set up a new server. The rest is in code and once you have it in place, it'll work on any server but that connection string gets me (almost) every time!

ColdFusion in the Cloud Revisited

About a month ago, I talked about my experience of setting up clustered ColdFusion instances on EC2. Since then we have migrated the Broadchoice Web Platform completely from a regular data center, where it had lived since launch, to the Amazon cloud and now all of the *.broadchoice.com sites and all of our client sites based on the Web Platform are happily running in the cloud.

We've been very pleased with the performance and stability of EC2 so far and we're comfortable about scaling out as demand increases. We took advantage of Amazon's EBS (Elastic Block Storage) that allows you to mount S3 storage directly as part of the file system on EC2. This essentially replaces the NAS we were using in the data center where all uploaded files were placed. We run two ColdFusion instances on a medium EC2 instance and run MySQL on a separate EC2 instance (actually on the instance that is currently running our AIR application, the Broadchoice Workspace for Salesforce, along with its MySQL database). We replicate the MySQL databases to another server (in a data center) so that we can restore / recover in the event of a problem with EC2. We also run scheduled backups of the EC2 instances to S3.

As I noted in my earlier entry, we're using Apache and the JRun Connector to manage the two instance cluster and failover. I'm still suspicious of the connector due to past experience but so far it has been behaving well and when we restart instances for maintenance, we're generally seeing uninterrupted service, from a user's point of view, as requests silently failover to the other instance.

If you're interested in running ColdFusion in the cloud, you'll need to talk to Adobe about licensing (either Adam Lehman or Kristen Schofield) but they are being very encouraging because they want this to happen. The more of us who do this, the better the argument they can present internally to get the EULA changed to support ColdFusion running in the cloud!

If you want to learn more about how we handled the migration and/or what to watch out for when designing applications that run well on the cloud, feel free to contact me via this blog or directly (c'mon, you know my email address!).

ColdFusion to Groovy - List issue

I recently ran into an interesting issue involving ColdFusion, Groovy, and Lists. I thought I'd share, but before I go any further, please remember that I am still very new to Groovy. There is a good chance that I may mis-label something. So with that said, what was the problem?

The mobile version of our application is a ColdFusion web site that speaks to Groovy via ColdSpring configured beans provided to our Model-Glue application. This makes it incredibly easy for me to reuse all the Groovy services we built for the AIR application. When I need to get some content, for example, I can do:


<cfset arguments.event.setValue("task", beans.contentService.getCurrentUserContentItem(javaCast("long",id)))>

The only clue that something non-CFML is going on here is with the javaCast. Outside of that I may as well be using a 100% pure CFML application.

In general, this just plain works. Period. However, last week I ran into an odd issue with one method that took a list as an argument. I knew that a list in Groovy was an ArrayList, and that should correspond to an array in ColdFusion. I created my object, let's call it ob, and then ran code similar to this:


<cfset beans.contentService.savePublications([ob])>

Note the use of [] to shortcut the need for me actually creating an array. If that is confusing, think of it as:


<cfset var arr = arrayNew(1)>
<cfset arr[1] = ob>
<cfset beans.contentService.savePublications(arr)>

That should work, right? Unfortunately it didn't. I kept getting errors saying that my data was some odd, generic Java object as opposed to the casted object it should have been within Groovy. I tried a few things - like for example, changing my closure from:


contentItems.each { contentToSave ->

more logic here....
}

To


contentItems.each { Content contentToSave ->

more logic here...
}

I thought maybe the extra hinting there would help. All that did was move the error up to the beginning of the closure. Eventually I gave up. I wrote a new method in Groovy that took a singular object and simply called the list version. While this worked, I wasn't terribly happy with it, and shared the problem with my coworker. Sean suggested that the problem may lie in the array ColdFusion was creating. He suggested using an ArrayList in CF and then passing that to Groovy. I modified my CFML like so:


<cfset var al = createObject("java", "java.util.ArrayList")>
<cfset pub = createObject("java", "com.broadchoice.bcp.model.beans.Publication")>
<cfset pub.content = bookmark>
<cfset pub.space = space>
<cfset al.add(pub)>
<cfset beans.contentService.savePublications(al)>

This worked like a charm. It was a bit more code to work with, but at least I could use the same service methods AIR was using for the same business logic.

ColdFusion in the Cloud (and clustering)

This week has seen my focus shift back from ActionScript / Groovy to ColdFusion, although not specifically programming in CFML. A couple of blogs have been buzzing about the pros and cons (and plain ol' whys) of running ColdFusion in the cloud, such as on Amazon's EC2 service. Obviously you can run Open BlueDragon or Railo without worrying about cost but for many people, only Adobe ColdFusion will really do what they need and the current EULA does not really accommodate that (partly because the "per 2 CPU" aspect doesn't cover the Amazon situation where you simply don't know how many physical CPUs you actually have!).

[More]

Email Testing on OSX

Yesterday I blogged about how I set up Groovy/Spring to send both HTML and plain text emails. Today I want to share a tip about testing those emails. I was using postfix on my Mac as SMTP server. This allowed Spring to connect to, and send the email, but the emails would never leave my machine. My coworker Sean had no problem with mail getting out, so I figured I either had some setting wrong or perhaps it was my cable company blocking the traffic.

I googled around a bit and came across this excellent blog article: fully local testing of email sending web apps (on Mac OS X)

This article describes how to set up postfix to listen to certain domain names and forward those emails to local account. It then goes on to describe how you can setup a pop3 server to get those mails.

The end result is that you can send email to anything at a particular domain and then use a desktop client to check the mail. This is not only cool for Groovy work but would also be useful for ColdFusion as well. I normally use Spoolmail to check CFML generated mail, but that isn't an option for Railo, and it doesn't give a 'perfect' end user view of the mail (especially for combo plain text/html emails like we are testing).

BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002. Contact Blog Owner