posted: 03 Feb 2012
Last night I launched my first attempt at a fluid/responsive grid layout for Bluemini.com. Using CSS3 media queries to apply different styles based on client width and a fallback basic fluid design for IE8 and lower that don't support CSS3, the outcome is very acceptable. I chose to only support 3+1 width configurations.
I didn't design it to be 'mobile first', but essentially, that's what it ended up doing. I render the HTML so that the natural order is how I want the content to display on the smallest screen. The basics of the layout come down to this
Wrapping the content and about with their own div means that it can be styled as its own entity and separately from the nav. Full screen: the wrapper gets floated right and the nav floated left (within wrapper content floated left, about floated right). Page has a max-width of old fixed with (990px) Middle: change the divs inside wrapper to both go full width so the content is above the about Narrow: essentially remove all float and the contents renders in natural order.
posted: 27 Jul 2011
One of the most useful (although not necessarily beautiful) parts of ColdFusion's toolset it the debug feature. This allows you to view the timings for all the parts that contribute to the final rendering of a page. It shows you a break down of all the queries that were run; their execution time, records returned and the full query body passed to the db.
However, getting an overview of the all queries, particularly comparing each query with the others, is difficult. Enter another great feature of CF, they provide the code they use to generate the debug pages, for you to tweak :)
So here is a simple piece of code that renders an easy to see comparison of the different query times running on the page. Add it to {jrun.home}/servers/{server.name}/cfusion-ear/cfusion-war/WEB-INF/debug/classic.cfm. I stuck it in at line 567, just after the template timings and exception summaries and before the full SQL Queries output.
<!--- Query Performance Graph --->
<cfoutput>
<cfif bFoundSQLQueries>
<cftry>
<p class="cfdebug">
<hr/>
<strong class="cfdebuglge">
<a name="cfdebug_querygraph">SQL Query Graph</a>
</strong>
</p>
<cfset maxQueryTime = 0>
<cfloop query="cfdebug_queries">
<cfset maxQueryTime = Max(cfdebug_queries.executionTime, maxQueryTime)>
</cfloop>
<table>
<cfloop query="cfdebug_queries">
<tr>
<td>#cfdebug_queries.name#</td>
<td>#Max(cfdebug_queries.executionTime, 0)#ms</td>
<td>
<div style="width: #Int(Max(cfdebug_queries.executionTime, 0)/maxQueryTime*100)#px; background-color: red; height: 10px"></div>
</td>
<td>#cfdebug_queries.template#</td>
</tr>
</cfloop>
</table>
<cfcatch>#cfcatch.message#</cfcatch>
</cftry>
</cfif>
</cfoutput>
You end up with something like this:

posted: 30 Jun 2011
I mentioned in this post that I had been having issues with cfhttp and uploading files. Well, the solution that I proposed in that post used a String object, into which the file contents were read, before assembling the response. This works well, but it does impose the overhead that the file is read into memory before being passed to the destination. This obviously starts to cause problems when we get large files being uploaded and so I started looking for another alternative.
I'm not sure what underpins the implementation of cfhttp in ColdFusion (I presumed in was Apache commons httpclient) but I thought I'd give that a go regardless, since it's already available to CF as it comes already inside the cfusion/libs directory. The 3.1 version has now been superseded, but I managed to locate the Javadocs and some example code, so thought I'd give it a try.
Here's what I came up with:
<cfset objFile = CreateObject("java", "java.io.File")>
<cfset objFile.init(filepathandname)>
<cfset uploadUrl = request.rhino.getLocal("docapiurl", true)>
<cfset commonsHttp = CreateObject("java", "org.apache.commons.httpclient.HttpClient")>
<cfset commonsHttpPost = CreateObject("java", "org.apache.commons.httpclient.methods.PostMethod")>
<cfset commonsHttpPost.init(uploadUrl)>
<cfset commonsHttpFilePart = CreateObject("java", "org.apache.commons.httpclient.methods.multipart.FilePart")>
<cfset fileName = GetFileFromPath(filepathandname)>
<cfset commonsHttpFilePart.init("file", filename, objFile)>
<cfset commonsHttpMeta = CreateObject("java", "org.apache.commons.httpclient.methods.multipart.StringPart")>
<cfset commonsHttpMeta.init("meta", xmlString)>
<cfset commonsHttpAction = CreateObject("java", "org.apache.commons.httpclient.methods.multipart.StringPart")>
<cfset commonsHttpAction.init("action", "upload")>
<cfset httpParts = [commonsHttpFilePart, commonsHttpMeta, commonsHttpAction]>
<cfset commonsHttpMultipartRequest = CreateObject("java", "org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity")>
<cfset commonsHttpMultipartRequest.init(httpParts, commonsHttpPost.getParams())>
<cfset commonsHttpPost.setRequestEntity(commonsHttpMultipartRequest)>
<cfset commonsHttp.getHttpConnectionManager().getParams().setConnectionTimeout(5000)>
<cfset status = commonsHttp.executeMethod(commonsHttpPost)>
<cfset uploadResponse = commonsHttpPost.getResponseBodyAsString()>
It seems to be working well, so in case you run in to cfhttp problems, give some Java a try.
Javadocs: http://hc.apache.org/httpclient-3.x/apidocs/index.html
Samples: http://svn.apache.org/viewvc/httpcomponents/oac.hc3x/trunk/src/examples/ (MultipartFileUploadApp.java
posted: 14 Jun 2011
I lived in California for two years, and whilst it didn't turn out to be the 'place for me' I was always impressed by their leadership on environmental issues. I'm sure these changes weren't always for altruistic ends, but hey, it made things a little better for the ordinary man in the street. Now they are looking to ban Styrofoam state wide! Fingers crossed, and I hope the trend catches on to other states (Washington?)
posted: 07 Jun 2011 As part of some expansion on our corporate intranet, I have begun building out a Documents API, similar to that from Google. The XML includes nodes that are more focused on our own particular business and internal arrangements, but pulls from the Google counterpart in many other ways. I wanted the API to be RESTful as far as possible and therefore needed to accept files directly via HTTP POST. Integrating this into an application seemed pretty straight forward, since CFHTTP allows you to specify a cfhttpparam with type="file", everything seemed sweet. Unfortunately, POSTing files through CFHTTP has given me a number of headaches, particularly with .docx files. The resulting file, saved via a pretty conventional CFFILE action="upload" process increases by 2 bytes! Which is somewhat annoying. Here's the code I was using: I've not done many parametric tests and haven't been able to identify if the 'Accept-Encoding' and 'TE' headers have caused the problems, but they are necessary to prevent any compression of the response which CFHttp doesn't like. So I took a delve into the HTTP spec and in the end, wrote my own HTTP body to achieve the result. I read the binary file in to a byte array 'myfile' using standard CFFile and then use this to initialize a Java String object using ISO-8859-1 character encoding. The divider can be any string that's not found anywhere else in the body, I don't scan for it, so there is a potential for conflict here, but the length of the hash makes it 'pretty' unlikely. The important thing to note here is that the Content-Disposition declaration comes immediately after the divider, that a single blank line separates the Content-Disposition declaration and the content of that POST field and that a single line follows this content before the next divider. The final thing to note is that dividers are all prefixed with '--' except for the terminal one, which is also suffixed with '--'. There may be a nicer way to achieve the 'string' response of the actual file data, HTTP being a text based protocol, the body has to be sent as a string, but for now, this approach is working. The most important thing during testing and getting this to work was that the character encoding was consistent and I found that 'ISO-8859-1' proved the best. UTF-8 didn't work so well.CFHttp issues with POST ing file content
<!--- to protect from web servers that compress the response --->
<cfhttpparam type="Header" name="Accept-Encoding" value="deflate;q=0">
<cfhttpparam type="Header" name="TE" value="deflate;q=0">
<cfhttpparam type="formfield" name="meta" value="#xmlString#">
<cfhttpparam type="formfield" name="action" value="upload">
<cfhttpparam type="file" name="file" file="#filepathandname#">
</cfhttp>
<cfset by="CreateObject("java","java.lang.String">
<cfset by.init(myfile, "iso-8859-1")>
<cfset contentdivider=Hash("this is my divider for this")>
<cfhttp method="POST" url="#uploadURL#" result="uploadResponse" charset="iso-8859-1">
<cfhttpparam type="header" name="Content-Type" value="multipart/form-data; boundary=#contentDivider#">
<cfhttpparam type="Header" name="Accept-Encoding" value="deflate;q=0">
<cfhttpparam type="Header" name="TE" value="deflate;q=0">
<cfhttpparam type="body" value="--#contentDivider#
Content-Disposition: form-data; name=""file""; filename=""#fileName#""
Content-Type: #mimeType#
#by.toString()#
--#contentDivider#
Content-Disposition: form-data; name=""meta""
#xmlString#
--#contentDivider#
Content-Disposition: form-data; name=""action""
upload
--#contentDivider#--">
posted: 06 May 2011
Increasingly, data is being held in memory caches on individual servers over a cluster of multiple machines, to reduce the load and latency associated with repeated lookups in a master data store. These caches are essentially key/value stores, held in application memory. Validity of the data in each cache is of greater importance than synchronicity so whilst notification of updates must be reliably cascaded out to all other nodes, the underlying data is not necessary. We have proposed and implemented a lightweight, difference based, approach to keeping cached data valid at the expense of keeping it synchronized using JMS message services.
A cache is only as valuable as the data that it holds. If that data is out of date (stale or invalid) then this can affect the users of systems that use the cache and ultimately leads to further problems with data integrity later on.
Synchronicity, on the other hand, was less of an issue. If one cache contained data that another cache did not, then the corresponding application could fetch the data from the master data store and save it to the cache. This relies on all servers in the cluster having appropriate access to the underlying data store.
One important aspect of this deferred synchronicity is that whenever any cache is updated, all other cluster members must be notified of the action and be able to validate their own copies of the data, if such a copy exists.
As discussed, it is not important that all caches contain the same data, rather it is important that the data that any cache contains is up to date. Hence we needed a mechanism to validate data whenever there was potential for it to change. To achieve this, the cache stores alongside each data node, a hash of the stored value. It uses this hash when both informing other caches of activity connected to a node and also when receiving messages related to a node, to discern whether cache related actions are required.
For current versions no data is passed over the JMS, only notifications that data has been somehow affected. When a node is inserted or modified, the key name that stores the data and the hash value are communicated in a message to all participants of the cache cluster.
Consider a two server setup where both servers have been recently started.
posted: 02 May 2011
I've been working quite hard recently on implementing a functional syntax style of programming that's implemented in CFML ( Anyway, I reached a pretty significant point in my development of FunctionalCF so I wanted to post about it to both record it and do a little advertisement for it. I've completely re-written the parser to now build a nested object hierarchy at function definition time, so that's made subsequent running of the function much more elegant. The parser is rather sweet too, with zero look ahead, it starts with a list object and then feeds that object character by character. The list object, is itself aware of how to interpret the incoming stream and as it sees characters such as (. [ and single quotes, it instantiates child objects to handle the stream. If there is a child object, the parent simply passes the data stream on and just takes note of the returned value. If the child object encounters the end of its own data stream, it will return a value to the parent to indicate such. One minor complication of this was that the character used to determine the termination of an object was in some cases required by the parent and in others not. The second big improvement is that the core now binds var placeholders, specified during the function definition stage, with the values passed in during execution. This is done by creating a bindMap structure in pure CFML and then passing this through all objects in the hierarchy. This data structure is also now defined in the IRunnable interface. If you care to check out this project, take a look at
posted: 22 Mar 2010 Today is World Water Day and for many this is a chance to challenge
societies dependence on bottled water. Providing usually lower quality
and more expensive water by bottle has been an ongoing campaign by the
large beverage companies over the past few years. However, now it looks
like the public are catching on. Bottled water sales have started to
drop and sales for those guys who make reusable bottles are going up,
but let's keep the trend going 'take back the tap'. The guys and gals over at 'Story of Stuff' have a great new film 'The
Story of Bottled Water
posted: 12 Feb 2010 ...to protect the guilty, from some recent minutes that I viewed! AB felt it would be helpful; HN agreed that there should be some form of
notification; PB agreed but only if it doesn't interfere with the user;
JS agreed with PB; KS agreed and GY agreed. posted: 03 Jan 2010 I took the decision today to lauch cfRhino onto RIAForge, to try and
give it a larger pressence in the CF community. I'm not really that
interested in gandering followers but I work hard on often on the
framework for work and personal purposes and so I thought I might as
well put it out there, in case someone is interested! I've linked to it
in the sidebar, I am working on the documentation a little, over a Sourceforge, but I
find that stuff really hard and I'm not having a great time of it so far! Anyway, if you're interested go check it out on RIAForge (or Sourceforge) Nick
Take back the tap
Names changed..
cfRhino on RIAForge
Bluemini.com is my website, named in honour of the Mini Classic, possibly the worlds greatest small car. I've had the site now for nearly two years and use it mainly as a developing ground for other sites. And I used to own a blue mini but alas not at the moment.
I pretty much use the site as a scrachpad for little projects that I am thinking about and working on; a collection of my ramblings (I hate to call it a blog), an online aggregator of RSS, an experiment in web watching, an attempt to view RSS in a newspaper format and some other stuff.
I hope you enjoy your stay and let me know what you think if you have strong opinions! Cheers
Bluemini uses the CFRhino framework, available from
SourceForge and via RIAForge. Under
continuous development since 2003, awesome...