StructureCMS

January 27, 2012

Using the SmarterStats Query API service in ColdFusion

Filed under: ColdFusion, Programming — joel.cass @ 3:53 pm

I must admit that it’s been a while since I’ve posted anything in this blog. To be honest, it’s mainly because there’s been nothing remarkable to post about. Nothing anyone would benefit from knowing, really.

It’s even to the point that my role involves much more than just programming these days – recently I have been involved in reviewing web statistics packages in the hope of landing on a solution. Well, the solution is found in SmarterStats – quite a remarkable web statistics package that does most things. It even has an API.

About that API – it has a largely undocumented ‘Query’ webservice. It is not enabled by default, but once enabled it allows you to query the statistics data via a web service.

To enable the service, you will need to create an authorisation key. A good one to use is a UUID. Then, you need to define that key in [SmarterStats_Root]\MRS\App_Data\Config\AppConfig.xml:

    <LocalHostDeleted>false</LocalHostDeleted>
++  <WebServiceAuthorizationCode>nnnnnnnn-nnnn-nnnn-nnnnnnnnnnnnnnnn</WebServiceAuthorizationCode>
    <ExpirationNotification />

Then you can access the service via http://localhost:9999/Services/Query.asmx, WSDL path http://localhost:9999/Services/Query.asmx?wsdl

The query service uses some form of psuedo-sql that runs a query against what looks like a function result, ie. SELECT * FROM fTableName(siteId, dateFrom, dateTo, maxItems, extraParam**) WHERE blah=blah ORDER BY blah.

** Parameters maxItems and extraParam are undocumented and were found by chance. MaxItems is pretty obvious, it’s the number of records to retrieve. Use extraParam to filter certain queries by page. Only certain queries support the extra parameter so try them out.

A list of tables is available in the file [SmarterStats_Root]\MRS\App_Data\Config\ReportConfig.xml – you can copy this to your development directory and then use it to generate a list of available reports.

Here are some example reports you can call using the web service (assume site id = 1):

  • Get Daily Site Traffic
    SELECT * FROM fActivityTotalTrend(1, '2012-01-01T00:00:00', '2012-01-27T00:00:00', 50)
  • Get Daily traffic to home page
    SELECT * FROM fDailyActivityForFile(1, '2012-01-01T00:00:00', '2012-01-27T00:00:00', 20, '/')
  • All pages, ordered by popularity
    SELECT * FROM fTopPages(1, '2012-01-01T00:00:00', '2012-01-27T00:00:00')
  • Top 10 most popular pages
    SELECT * FROM fTopPages(1, '2012-01-01T00:00:00', '2012-01-27T00:00:00', 10)
  • Web browsers
    SELECT * FROM fBrowsers(1, '2012-01-01T00:00:00', '2012-01-27T00:00:00')
  • Visitors by City
    SELECT * FROM fGeographicCountryByCity(1, '2012-01-01T00:00:00', '2012-01-27T00:00:00')
  • Visitors by City, to a certain URL
    SELECT * FROM fGeographicsByFile(1, '2012-01-01T00:00:00', '2012-01-27T00:00:00', 20, '/some/url/')

Calling the web service from coldfusion is pretty easy:

<cfsetting enablecfoutputonly="true">

<!--- 'static' service parameters --->
<cfset strUsername = "username">
<cfset strPassword = "password">
<cfset strAuthCode = "nnnnnnnn-nnnn-nnnn-nnnnnnnnnnnnnnnn">
<cfset strWebServiceUrl = "http://127.0.0.1:9999/Services/Query.asmx?wsdl">

<!--- initialise web service --->
<cfset objWebService = createObject("webservice", strWebServiceUrl)>

<!--- query parameters (you can pass these in from a form) --->
<cfset strReport = "fTopPages">
<cfset numSiteId = 1>
<cfset dateFrom = createDate(year(now()), month(now()), 1)>
<cfset dateTo = createDate(year(now()), month(now()), day(now()))>
<cfset numRows = 20>

<!--- compose query --->
<cfset strQuery = "SELECT * FROM #strReport#(#numSiteId#, '#dateformat(dateFrom,'yyyy-mm-dd')#T00:00:00', '#dateformat(dateTo,'yyyy-mm-dd')#T00:00:00')">

<!--- execute query --->
<cfset dsResult = objWebservice.executeQuery(strUsername, strPassword, strAuthCode, numSiteId, strQuery, numRows)>

<!--- convert to query --->
<cfset qryResult = datasetToQuery(dsResult, 'Table1')><!--- version 7: it is 'Table1', version 6: it is 'results' --->

<!--- output result --->
<cfdump var="#qryResult#">

<!--- FUNCTION TO CONVERT .NET DATASET TO QUERY (added here for convenience - move to helper class) --->

<cffunction name="datasetToQuery" access="public" returntype="query" output="false">
	<cfargument type="any" name="dataset" required="true">
	<cfargument type="string" name="tablename" required="true">

	<!--- dataset has 2 nodes: 1) Column definitions 2) Data --->

	<cfset var qryResult = "">
	<cfset var lstColumns = "">
	<cfset var lstTypes = "">
	<cfset var aryDataset = ARGUMENTS.dataset.get_any()>
	<cfset var aryColumns = XmlSearch(aryDataset[1].getAsString(), "/xs:schema/xs:element[@name='#ARGUMENTS.tablename#']/xs:complexType/xs:sequence/xs:element")>
	<cfset var aryData = XmlSearch(aryDataset[2].getAsString(), "/diffgr:diffgram/NewDataSet/#ARGUMENTS.tablename#")>
	<cfset var i = 0>
	<cfset var c = 0>

	<!--- get columns --->
	<cfloop from="1" to="#arrayLen(aryColumns)#" index="i">
		<cfset lstColumns = listAppend(lstColumns, aryColumns[i].xmlAttributes.name)>
		<cfswitch expression="#aryColumns[i].xmlAttributes.type#">
			<cfcase value="xs:double,xs:long">
				<cfset lstTypes = listAppend(lstTypes, 'double')>
			</cfcase>
			<cfcase value="xs:date">
				<cfset lstTypes = listAppend(lstTypes, 'timestamp')>
			</cfcase>
			<cfdefaultcase>
				<cfset lstTypes = listAppend(lstTypes, 'varchar')>
			</cfdefaultcase>
		</cfswitch>
	</cfloop>

	<!--- create query object --->
	<cfset qryResult = queryNew(lstColumns, lstTypes)>

	<!--- populate query --->
	<cfloop from="1" to="#arrayLen(aryData)#" index="i">
		<cfset queryAddRow(qryResult)>
		<cfloop from="1" to="#arrayLen(aryData[i].xmlChildren)#" index="c">
			<cfset querySetCell(qryResult, aryData[i].xmlChildren[c].xmlName, aryData[i].xmlChildren[c].xmlText)>
		</cfloop>
	</cfloop>

	<cfreturn qryResult>
</cffunction>

<cfsetting enablecfoutputonly="false">

All this was tested in SmarterStats 7.

November 7, 2011

Sydney to Gong – a big thanks

Filed under: Cycling — joel.cass @ 7:58 am
The Cellarbrations Team

Sydney to gong is over again, and thank you all who have supported me and helped fundraise over $400.

This year was different, as I wasnt riding alone this time, but instead as part of “team cellarbrations”, affiliated with the LACC and my previous employer, metcash.

What also made this year different was the lack of sleep, as it just happened that the Janet Jackson concert was the night before. With only 3 hours of sleep, it was a bit of a stretch for me.

At any rate, I managed to better last years’ attempt, having arrived before 9am. According to the speedo it was about 2 hrs and 38 minutes. It was different riding in a team but just as enjoyable.

September 14, 2011

Sydney to Gong – It’s on again!

Filed under: Cycling — joel.cass @ 4:20 pm



It’s on again!

I have entered the 2011 MS Sydney to the Gong Bike Ride and have committed to fundraise $1000.00 in support of people living with Multiple Sclerosis. This year MS Australia aims to raise $4.5 Million through the event, and I want to play my part and “ride for a purpose”.

Multiple Sclerosis is a disease of the central nervous system affecting more young adult Australians than any other neurological condition. Your donation will go directly towards providing a wide range of services and support to people living with MS.

Did you know?
- The average age of diagnosis of MS is just 30 years
- 3 times more women than men are affected by MS
- An estimated 20,000 people in Australia have MS
- There is no known cause or cure

Please take a moment to view my online fundraising web page and help me reach my goal. It”s quick and easy. You can donate securely online using your credit card by clicking on the link below:
http://register.gongride.org.au/2011-Sydney-to-Gong-Ride/jozza81/e

All information is secure and all donations will be sent electronically to MS Australia ACT/NSW/VIC. A tax-deductible receipt will automatically be emailed to you once the donation is verified.

Your support is greatly appreciated.

August 17, 2011

ColdFusion on Linux – Make sure your hostname is correct!

Filed under: ColdFusion, Technology — joel.cass @ 10:52 am

Recently I have been given the task to install ColdFusion on CentOS. Everything went well, Apache installed fine, related dependencies installed fine, even ColdFusion installed fine. Until I tried accessing the site, upon which I was presented with this error:

java.lang.NullPointerException
	at java.lang.String.indexOf(String.java:1733)
	at java.lang.String.indexOf(String.java:1715)
	at jrun.servlet.session.SessionService.getUrlSessionID(SessionService.java:1097)
	at jrun.servlet.ForwardRequest.getRequestedSessionId(ForwardRequest.java:426)
	at jrun.servlet.ForwardRequest.isRequestedSessionIdValid(ForwardRequest.java:467)
	at jrun.servlet.ForwardRequest.getSession(ForwardRequest.java:344)
	at jrun.servlet.ForwardRequest.create(ForwardRequest.java:135)
	at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:253)
	at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)
	at jrun.servlet.http.WebService.invokeRunnable(WebService.java:172)
	at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
	at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)

I had installed ColdFusion 9, in a similar method to that described here. So, I tried installing ColdFusion 8 following the same method. Still got the error. I then tried installing ColdFusion 9 to use the root user (not recommended). Still got the error.

So I pulled my hair out for a bit, and then started scanning logs, upon which I came across this line:

08/16 23:23:54 error centostemplate.xxxx.xxx.au: centostemplate.xxxx.xxx.au
java.net.UnknownHostException: centostemplate.xxxx.xxx.au: centostemplate.xxxx.xxx.au

…and then it all fell together! The instance I had been given was created off a template, in which the host name was set in /etc/sysconfig/network to ‘centostemplate.xxxx.xxx.au’ – which did not resolve via DNS! So, the easy fix was to map this over in /etc/hosts to localhost, i.e.

127.0.0.1    centostemplate.xxxx.xxx.au

Restart the services, fixed! This is CentOS in my case, but I think if you ever run into this problem on a *nix platform, check your network config and ensure that your configured hostname resolves to an IP address.

June 30, 2011

Telstra wireless broadband – lessons learned

Filed under: Technology — joel.cass @ 8:16 am

Telstra sucks. It’s a well-known fact and while I’ve avoided being a customer of theirs for the last 10 years or so, I’ve been having a lot of trouble getting coverage from my Vodafone wireless broadband service. So, I walked into a Telstra store, purchased a prepaid Internet router (Telstra Elite) from the reluctant staff member who then proceeded to take copies of my driver’s licence (don’t know why since I had to fill in all the details all over again), opened the package, read the instructions, it all seemed so ’simple’.

Yet, when I actually try using the thing it doesn’t work. First things first, the card provided with the modem says you can be connected in *just* 3 simple steps! Wrong! The manual actually mentions (on an left-sided page with no headings) that you have to actually activate the modem by calling a number. Simple.

I call the number. Automated message tells me I should go online, after all, it’s “quick and easy”(!). I hate automated phone services, so I decided to go online. Fill out all my details and then, theoretically, my modem should be activated in the next two hours. The next morning I try to connect (about 12 hours later). I still can’t connect.

I check the modem settings. Fine, no problem there. The connection between my laptop and the modem is very fast. I click on the ‘check your account’ link. It loads! Oh, I have zero credit. But what about the 5GB included with the modem? It looks like I’ll need to buy credit before I can use my ‘bonus’ credit. Fucking Telstra!!!

So I give the call centre a call. Following the prompts, got there eventually. I was served by someone named ‘Joy’ – oh the irony. After resetting my modem, and resetting the computer (she asked me if it was ‘XP or Vista’ – ha it’s a Mac!), everything just magically worked.

I refreshed the ‘My Account’ page – miraculously a dollar was added to my credit! And everything just seemed to work!

Two hours later I check to see if it’s still working. Nope. Broken again. I refresh the ‘My Account’ screen. Zero credit again!

I call up again, this time I am greeted by Mark. He starts rolling out the normal questions, asking me to reboot my computer etc etc. Check the SIM card, fine, fine, fine… Then he realises my account was set up as a mobile phone account!

The whole problem was that I used the Internet to enable my prepaid broadband service – it can only be enabled over the phone. Hence, they don’t mention the Internet in the manual – however, the greeting when calling to activate the account starts off by recommending that you go online to enable your account, after all, it’s “quick and easy”! It was neither quick, nor easy, in fact, it was painful!

What I can’t stand about Telstra’s approach is how many times the words ’simply’, ‘easily’, and ‘just’ were mentioned in their documentation and on the prerecorded phone messages – not only is it patronising but it’s an outright lie! The documentation should read as follows:

You can set up your modem in 7 easy steps!

  1. Simply crack your nails trying to open the back shell of the modem. Easily realise that isn’t working, and then just use the corner of a credit card to crack the shell open.
  2. Simply insert the battery into the back of the modem so that the contacts meet the pins (which aren’t gold by the way).
  3. Put the blue card that came with your modem in front of you. Turn on your computer, and set up a new wireless network. Select the network name entered on the card and enter your WPA password.
  4. 4. Simply open up a web browser and realise nothing is working. Open a new window and enter ‘http://192.168.0.1′ into the address bar – a page should load up immediately. This confirms that you have your network set up correctly.
  5. Call 125 8887 and follow the prompts to activate your card. DO NOT go on the Internet to activate the card.
  6. Simply Wait 2 hours
  7. Check to see if your account works. If not, call 125 8887 and simply follow the prompts (4, 2, 1). Consult your friend at the other end of the line.
  8. Repeat step 7 as many times as necessary. Step 6 may be necessary as well.

But this will never be a reality. Telstra seem to assume that their customers cannot count past 3 and also, the process is not ’simple’ nor is it ‘quick’ and ‘easy’.

Great network, poor systems, and a workforce that knows nothing about the customer. Enter Telstra. And people wonder why their shares don’t get good returns.

May 24, 2011

The Great Hunter Cycling Classic

Filed under: Cycling — joel.cass @ 8:22 am

The Great Hunter Cycling Classic (or the all spokes festival as it is also known by) is a series of races held in the Hunter Valley, first a criterium on Saturday, then a 60 or 100 kilometre race held on Sunday. This was my first time at this race, and also the third race I had signed up for. Being as dumb and naive as I were, I decided I could do the 100km race. After all, I’ve done many 100km rides without issue, I should be able to hold my own. At least that’s what I was thinking…

I missed the criteriums, mainly because I don’t have the right license, but arrived on Sunday morning for registration and warm-up. Registration was easy; however pinning the numbers on took more time than it should
have. By 7:50 I was ready for warm-ups, which gave me barely 15 minutes. I still felt lethargic from the night before and the lack of a hearty breakfast.

Being such a long race, I was expecting it to start softly and then go from there. It was quite the opposite. As soon as the start was announced, everyone took off. The pace soon lifted to around 50km/h. Then it lifted again. I could feel my legs already, I was not prepared for such a start. After trying to hold on for about 10km the peloton started creeping away. And after the second hill I knew I could not catch them no more.

So I resigned to a recovery pace for a while, sticking it to around 30-35km/h. A few more hills and a couple of corners later I was passed by another group. I tacked onto the back of them and found their pace a lot more comfortable, sitting between 35-40km/h.

The next thing I didn’t see coming was the straight leading up the the finish line. The were more potholes on the road then there were bitumen. Just one awful patch-up job after the next. Going over these sections at 40km/h could be likened to sitting on top of an out of control machine gun. The bike was going everywhere. I dropped my chain at least once.. Lucky it was on the big ring.

The first lap was done and it was onto the second. Now the group had gotten a rhythm and everyone was humming along rather well. More hills, more potholes, and then another lap of the same. By the end of the fourth lap I could really feel my legs. Furthermore, the group was starting to pick up given that the final lap was around the corner.

In my mind, I fell as if my body had almost resigned that the last lap was a cool-down session, as soon as I passed the line everything just caved in. At the first hill my legs cramped up, one started working against the other. Things started getting a bit blurry and I found myself in a world of pain. I drank some water – it tasted like domestos – why did I have to fill my bottles at the hotel? Soon I saw my group fade into the distance. Then I was on my own.

It was a struggle. My legs aching, my chest sore, nothing top do but find a gear where I could sit comfortably at 90rpm and forget any chances of winning or even doing well. What was I thinking that I even had a chance? These guys were way too fast, and furthermore all my 100k rides have had breaks in them.

Soon it became a matter of mind versus body. Things were shutting down left right and centre. I started getting tunnel vision. My legs weren’t getting any better. I kept my eyes on the speedo. “90rpm”, I remind
myself, “keep it at 90rpm” – the hills came and I was out of gears. “Out of gears on a 6% incline? What’s wrong with you?” things start getting nasty and every antagonistic, anxiety-inducing thought comes out to play. Then it turns to “that bank on the left looks nice, lets get some sleep”, or just plain “ow, ow, ow, ow, ow”…

Finally the last corner comes in. I pass one guy that was obviously in the same world of pain I was. We shouted some encouraging words back at each other but soon lost touch. The potholes come around again and it’s almost as if my legs had come back to life – perhaps it were the bumps triggering some sort of adrenalin rush, or just that my legs had recovered whilst riding at snail pace.

I was counting the hills to the finish line, 3… 2… 1… The finish line was in sight – before I knew it, the 500m sign past, then 200m, 100m and then all I could hear were gears grinding – in the last 100m a group of riders passes. Where were they before? At any rate I placed somewhere in the middle of them and the race was over. And strangely I did not feel tired, exhausted, nor exhilarated. Just plain relaxed that it was all over. I guess I found my limits and experienced phenomenon I had only read about, in the end I was glad just to have finished.

It pays to set goals. My goals started out ambitious – “keep up with the group”, “try some tactics”, “have a good sprint at the finish”… It soon changed to “finish the race”, “don’t pass out”, “don’t throw up”… Funny how things change on the day and I always find myself short of preparation.

In the end it was a good ride, the scenery was excellent, the weather perfect, and even though there was a lot of pain, I had learned a lot about my limits. And I actually came out of the race feeling good, like it was all just one big workout. A coffee, a little bit of food and it was time to head back to the big smoke to recover whatever was left of the weekend.

February 9, 2011

Retrieving HTTP URLs in PHP

Filed under: PHP — joel.cass @ 9:32 am

It’s strange how many different ways there are to do the same thing in PHP. For example,if you want to retrieve a URL, it can be as easy as calling file_get_contents($url), or you can use the PECL libraries, or you can go dig up an open source project such as this one.

I was messing around one night and figured it would be possible to just run an http request over a socket. As it turns out it’s not so difficult, there is tons of information out there on how to do it and it wasn’t long before I had a method figured out.

The advantage of this is that it is lightweight and gives you some control over the headers (etc) that you want to send/receive. This has only been tested on text-only requests.

function get_http_content ($url, $timeout = 3, $headers = array()) {
	// initialise return variable
	$stcReturn = array("headers"=>array(), "content"=>"");

	// get server name, port, path from URL
	$strRegex = "/^(http[s]?)\:\/\/([^\:\/]+)[\:]?([0-9]*)(.*)$/";
	$strServer = preg_replace($strRegex,"$2",$url);
	$strPath = preg_replace($strRegex,"$4",$url);
	$numPort = preg_replace($strRegex,"$3",$url);
	if ($numPort == "") {
		if (preg_replace($strRegex,"$1",$url) == "https") {
			$stcReturn["headers"]["Status-Code"] = "0";
			$stcReturn["headers"]["Status"] = "HTTPS is not supported";
			$stcReturn["content"] = "Error: HTTPS is not supported";
		} else {
			$numPort = 80;
		}
	}

	// connect to server, run request
	$objSocket = fsockopen($strServer, $numPort, $numError, $strError, $timeout);
	if (!$objSocket) {
		// connection not possible
		$stcReturn["headers"]["Status-Code"] = $numError;
		$stcReturn["headers"]["Status"] = $strError;
		$stcReturn["content"] = "Error: {$strError} ({$numError})";
	} else {
		// connection made - send headers
		$strOut = "GET {$strPath} HTTP/1.1\r\n";
		$strOut .= "Host: {$strServer}\r\n";
		$strOut .= "Connection: Close\r\n";
		foreach ($headers as $strName=>$strValue) {
		$strOut .= "$strName: $strValue\r\n";
	}
	$strOut .= "\r\n";
	// get data
	fwrite($objSocket, $strOut);
	$strIn = "";
	while (!feof($objSocket)) {
		$strIn .= fgets($objSocket, 128);
	}
	fclose($objSocket);

	// split data into lines
	$aryIn = explode("\r\n", $strIn);

	// data is split into headers/content by double CR
	$bHeader = true;
		foreach ($aryIn as $i=>$strLine) {
			if ($i == 0) {
				// first line is [protocol] [status code] [status]
				$stcReturn["headers"]["Protocol"] = preg_replace("/^([^ ]+) ([^ ]+) (.+)$/", "$1", $strLine);
				$stcReturn["headers"]["Status-Code"] = preg_replace("/^([^ ]+) ([^ ]+) (.+)$/", "$2", $strLine);
				$stcReturn["headers"]["Status"] = preg_replace("/^([^ ]+) ([^ ]+) (.+)$/", "$3", $strLine);
			} elseif ($bHeader && $strLine == "") {
				// if line is empty headers have ended
				$bHeader = false;
			} elseif ($bHeader) {
				// set header
				$stcReturn["headers"][preg_replace("/^([^\:]+)\:[ ]*(.+)$/", "$1", $strLine)] = preg_replace("/^([^\:]+)\:[ ]*(.+)$/", "$2", $strLine);
			} else {
				// set content
				$stcReturn["content"] .= $strLine;
				if ($i < count($aryIn)-1) {
					$stcReturn["content"] .= "\r\n";
				}
			}
		}
	}
	return $stcReturn;
}

January 4, 2011

Cycling in Jervis bay

Filed under: Cycling — joel.cass @ 11:52 am

This new years’ break was spent at the beautiful Hyams Beach in Jervis Bay NSW. Whilst the weather was not fantastic (apart from a few days thankfully), the cold and cloudy mornings allowed me to get some cycling time in. I had decided to take the commuter bike down the coast as it is an MTB, even though it had the slicks fitted it could still be taken off-road.

It’s strange that so many people do not consider Jervis bay as a cycling destination. At least in the early morning, the roads are rather quiet, there is no shortage of wildlife to see, and whilst there are many hills most of them are mild and rolling. There were many times that I would be the only one on the road – only the hum of the tyres and the birds’ calls filled the air. No traffic. No pedestrians. No pollution.

It was not long before I found a good route to take. The Shoalhaven city council has listed numerous rides on their website, the most appropriate ride I found was ride A15 – this ride is probably the closest to the Hyams Beach and did not involve riding on the beach at low tide (unfortunately it was always high tide whenever I wanted to ride). The A15 ride took in views of the Basin and also of the country around the Jervis bay area. And back along the urban tourist drive for good measure.

I had seen on google maps that there were tracks leading from the Vincentia golf club through the bush to Hyams beach. I decided to take this route and it was quite rewarding. Even though the MTB had the Schwalbe Kojak slicks fitted they handled well, although they did get a bit ‘taily’ in the sandy areas. They were excellent on the gravel and rocks, and even held their own in muddy areas, surprisingly. The last 2km or so leading down to the beach was almost entirely downhill, allowing the bike to pick up some speed and for me to test out the tyres. They did well, though packing for home it was obvious why the manufacturer did not recommend them for off-road use – there were many abrasions on the sidewalls, but no cuts (I wish road tyres were made that well).

I have posted two rides to bikely.com:

  • Road Loop, a basic ride on the road
  • MTB Loop, including a tour of Sanctuary Bay and the off-road portion after the golf course

Here’s some photos I took on the ride. As you can see, there is quite some nice scenery and wildlife (I did actually ride straight past that Kangaroo but was too wimpy to get close to it later to take a photo).

Sunrise from Sanctuary bay

Kangaroo at Sanctuary bay

Scenic Valley after Tomerong (It's not as steep as you think)

The view from Greenfields beach

Lookout point between Greenfields and Chinamans Beach

December 7, 2010

Configuring ColdFusion to have different JVM Settings per instance

Filed under: ColdFusion, Programming — joel.cass @ 9:08 am

Recently I had upgraded a ColdFusion server from standalone to multiple instance. This was easy – basically a matter of installing a new copy of ColdFusion as multi instance and copying the settings from the standalone instance. However, the issue has now arisen that every app on the server is to run as it’s own instance and if they all share the same settings, there will not be enough memory to run each instance smoothly.

The problem is, that some instances will require more memory while some will require less. Adobe had posted how to do this on their website but it seems to have been deleted recently. Luckily the instructions were still available google cache! I’ve copied the instructions here for later reference. As I will forget…

Basically, it’s three steps:

  1. Open up the JRun/bin directory
  2. Copy jvm.config to jvm_<server_name>.config
  3. Configure the startup script by
    • Windows: use jrunsvc -remove "<service_name>", then jrunsvc -install <server_name> <server_name> "<service_name>" -config jvm_<server_name>.config
    • Linux/Unix/Mac: add -config jvm_<server_name>.config to the startup command, e.g. jrun -start default -config jvm_<server_name>.config

* <server_name> is the name of the folder under the JRun/servers directory that contains the server, e.g “cfusion”
** <service_name> is the name of the service in windows, e.g. “Macromedia JRun cfusion Service”

November 24, 2010

Bicycle gearing calculator

Filed under: Cycling — joel.cass @ 3:17 pm

I know there’s a few of these around on the Internet but I thought it would be nice to create one of my own. The gearing calculator shows you what sort of speeds you can get out of your current gearing. Also, I’ve added things such as gear inches and gain ratio. The gain ratio even takes into account the crank length that you are using, amongst other things.

Try it out here: Bicycle Gear Calculator

Bicycle Gearing Chart

Bicycle Gearing Chart

Older Posts »