Welcome!

ColdFusion Authors: Yakov Fain, Pat Romanski, Liz McMillan, Maureen O'Gara, Greg Ness

Related Topics: ColdFusion

ColdFusion: Article

HTTP Status Codes: Do the Unthinkable

Implement threading using CFML

HTTP status codes can help you implement threading and more. Here are a couple of ideas.

Although the power of ColdFusion allows us as developers to do many things very quickly compared to many other languages, there are times when we find CFML does not offer all of the functionality required to accomplish a task. It can be quite frustrating to find that your end result of many hours of programming is limited by your tools, rather than your skills or experience. In this article, I will show you how to implement a couple of interesting and relatively simple solutions to problems I've come across in the past, through the use of an oftentimes underutilized tool - HTTP status codes.

Have you visited Web sites that had a simple HTML form for voting that was able to tally your vote without refreshing the page? On the surface, it would seem that this was accomplished through JavaScript, but it's actually done by HTTP status codes. Using our sample application, the ColdFusion MX Hotfix Center, I will show you how you can do this yourself. I've also implemented another example into the sample application showing how to leverage status codes to implement a scaled-down version of threading using ColdFusion MX.

Admittedly, the specific techniques used in this article are perhaps not applicable to all typical Web applications. For instance, the first example could also be done in Flash, but I included it just as an example of what you could potentially use HTTP status codes to do. However, I have found the use of HTTP status codes very useful when working in complex, multitiered environments with slow third-party resources that a ColdFusion application is dependent on. A specific example of this is a situation I've worked on in the past: a ColdFusion application that connected to a slow legacy database system for reporting. Because the legacy database system took tens of seconds instead of milliseconds to return queries, it was very useful to run each query simultaneously using HTTP status codes - instead of one at a time - to vastly speed up the application.

The HTTP Protocol
The HTTP protocol is a completely separate subject of its own, so I'll just briefly brush over it in case you are not familiar with its general premise. When a client (such as a Web browser) makes a request to a Web server, HTTP status codes are returned to the client in the header of the Web server HTTP response. The client uses these codes to decide which action it should perform. For instance, if the client receives a code of "200", which is "OK", it knows the page was found and has been returned in the body of the response. In the examples that follow, we will concentrate on a specific status code: status code 204. If you'd like to read more about the HTTP protocol, please check the Resources section at the end of this article for links that describe it in detail.

HTTP status code 204 essentially tells the client to not change what it's displaying, as there is no content coming back from the server. What does this mean? In a nutshell, it allows users to submit information without having to wait for the page to reload, much as if they were using a Flash-based form. This minor detail is very powerful at the presentation level, in addition to providing us with a way to implement a scaled-down version of threading using ColdFusion MX.

Environment Setup
The ColdFusion MX Hotfix Center is a quick application I wrote to show a couple of simple possibilities using status code 204. To make it easier to install and use, I chose to create a simple XML file rather than a database, so you will need to make sure the ColdFusion MX 6.1 server you use for this sample has the <cffile> tag enabled, and that the server can access the Internet, as I also use the <cfhttp> tag to download hotfixes.

After confirming the aforementioned details on your ColdFusion server, I highly recommend downloading the sample code in this application from the ColdFusion Developer's Journal site (www.sys-con.com/coldfusion/sourcec.cfm) and deploying it into a subdirectory named "hotfix". From there, you will need to open the Application.cfm file and make sure the configuration lines shown in Listing 1 are set up correctly for your environment.

After you've saved your changes to this file to reflect your environment, you should be able to browse to the index.cfm file of the application via a Web browser, and it will return a page that looks similar to the one shown in Figure 1. If you see a page similar to this, you are ready to continue.

Voting Example
Often seen on news sites, blogs, and various other forums on the Web, voting is a powerful way for Web site owners to gather information from their visitors. It's very simple for visitors to participate, and they usually don't mind taking a few seconds to vote on an issue that is presented to them.

In our first bit of code contained within index.cfm (see Listing 2), we will implement a simple form that is dynamically generated by the XML mentioned earlier. This component then posts the vote information to be tallied back to our Hotfix component, hotfix.cfc.

As you can see, it's just a basic HTML form that posts to the hotfix.cfc. method. We are also calling the small bit of inline JavaScript in the index.cfm file to disable the submit button in this form after it's been submitted so that a user is not able to vote more than once (see Listing 3).

Of course there are also a lot of other considerations to take into account when creating a voting system - such as how to avoid duplicate votes, for instance - but those issues are outside the scope of this article.

Listing 4 shows the important functions from hotfix.cfc that are involved with tallying the votes coming from this form, as well as returning the status code 204 to our Web browser.

The first, tallyVote, is the function that accepts the form post and updates the Request scope to reflect the new vote. The second function shown in Listing 4, return204, which tallyVote calls, returns the status code 204 to our browser, and thus ends the request as far as our browser is concerned.

To test this functionality using your browser, cast a few votes, and then refresh the page in your browser. Notice how the vote tally has changed? Each time you submitted the form, the server responded to your browser with the 204 status code, and it did not try to refresh the page or load other content.

Not bad for a few lines of code, eh? This is obviously a very simple thing to do, but it's used so rarely on the Web that I wanted to show other developers the power of using it. The code in Listing 4 represents a pretty basic example of how to use status codes. We'll extend that idea in the next section.

Threading Overview
As a programmer with a traditional software development background, one of the things I repeatedly cite as a shortcoming of the ColdFusion language is the lack of threading support within CFML. Granted, the ColdFusion MX server itself is multithreaded, as it handles simultaneous requests; however, there is no mechanism for spawning threads within the language itself.

According to recent blog entries and user presentations about Blackstone, the next version of ColdFusion MX will include threading support. Until then, we still have problems we need to solve - and finding a way to do threading was one of them - until now.

Threading, like the HTTP protocol, is a topic on which books have been written, so I will cover only a few basics here. Essentially, threading is a way of assigning tasks to parallel processes so they can be run at the same time, rather than serially, in which case one process or function must finish what it's doing before the next will be run. Traditionally, threading is most often used in languages like C++ or Java in GUI applications that need to spawn threads to perform operations in the background while the display of an application is doing something else, such as updating the user on the status of a thread that it spawned in the background. An example of this would be the status bar you are shown when copying a file in Windows. The file copying is a spawned thread running in the background, while the display updates itself as the files are copied.

In most Web applications, it's not quite as obvious where having threading functionality would be a big advantage. However, in enterprise-level applications, having threading at your disposal is more necessity than desire. A prime example would be a reporting application that has to run many queries, all of which take a long time to complete; firing all of these queries off at the same time in parallel would cut down the processing time significantly.

Implementing Threading in ColdFusion MX
Accomplishing threading in CFMX is not much different from our first code example. We still need to return the same 204 status code to our client; however, this time our client will actually be the <cfhttp> tag. Keep in mind that the performance drawbacks associated with making HTTP requests must always be weighed against the possible benefits of their use. That said, there are some interesting real-world uses for multiple simultaneous requests.

In this example we will use threading to download to the server all of the hotfixes contained in the hotfix.xml file. First, you will want to open up the index.cfm file from the source code and scroll down to take a look at the simple form that downloads all of the hotfixes at the same time (see Listing 5).

This form is posted to hotfix.cfc, calling the method threadDownloads, (see Listing 6), which is the one that actually spawns all of the new threads by looping through the various hotfix IDs and establishing a <cfhttp> call for each one to invoke a new thread, which downloads that particular hotfix to the server.

Caveats to These Techniques
Because the above example of threading is essentially akin to spawning off extra processes, extra planning is required to get them to work depending on how you decide to implement this technique. For many types of the operations that you may wish to thread, it will take quite a bit more effort than traditional threading, as each thread is actually a separately spawned process rather than something that is part of the process, including the same RAM and environment as the process which spawned the thread.

Given that each "thread" is really just a separate request, you will have to find a way for the results of the spawned thread to talk back to the process that spawned them, if they are supposed to be returning data. One of the ways I have currently implemented this is a threading system that uses its own internal status codes and stores the results of a given thread in a database using WDDX encoding.

Once the parent process queries the database and finds that a thread is done, it's able to get its stored results out of the database.

When using this technique you will need to make sure that you have debugging turned off. If any debugging or other output is returned to the client, it will actually wait for the request to finish as well as displaying whatever is returned in plain text format, thereby defeating the purpose of using your own status codes.

Conclusion
Although these techniques are pretty simple to implement, either very few people are aware of them or very little has been written about them online. The samples I've given you for using HTTP status codes are pretty basic in nature, but I hope they will provide you as a ColdFusion developer with an additional tool to use. I definitely look forward to seeing how others use this technique in their Web applications, and hope that you find it as useful as I have.

Resources

  • RFC 2616 - HTTP 1.1: www.w3.org/Protocols/History.html#HTTP11
  • HTTP 1.1 Status Code Definitions: www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

    Acknowledgments
    I would like to thank Jake Sutton and Neal Enssle for contributing brainpower to figuring out these techniques. It was definitely a group effort to stumble upon this gem and find interesting ways to implement it.

  • More Stories By Brandon Harper

    Brandon Harper has been programming in ColdFusion since 1998 and also actively writes applications in Python and Java. He is currently a Senior Software Developer at Acxiom where he works on an enterprise service platform which powers their risk mitigation products. Brandon was also a technical editor for Inside ColdFusion MX, and maintains a blog at devnulled.com.

    Comments (3) View Comments

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


    Most Recent Comments
    Brandon Harper 02/21/05 11:56:27 PM EST

    Hopefully I won't get in trouble for doing this (and if so, feel free to delete my comment SysCon), but you can grab the source code here since the link in the article is incorrect:

    http://devnulled.com/media/code/HotfixCenter.zip

    Thanks,

    - Brandon

    Otoniel Rojas 12/17/04 03:17:27 PM EST

    First the positive: It's a very revealing to know about the functionality of 204 http status code. But a few shortcomings in the article revealed a not functioning, incomplete sample coding.
    Where is the init() function called on listing 1?
    Where is the xml file?

    Dave Phipps 10/25/04 05:26:14 AM EDT

    Great article, very interesting. It is a shame that the code listing is not complete. The xml file is missing and the link to download (www.sys-con.com/coldfusion/sourcec.cfm) does not take you to the source code.

    Any chance of getting hold of the source code in a zip file?