<?xml version="1.0" encoding="iso-8859-1"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Greg Luck&apos;s WebLog</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/" />
<modified>2009-06-26T09:26:47Z</modified>
<tagline>The opinions expressed here are those of the author, not of my employer or clients.</tagline>
<id>tag:gregluck.com,2009:/blog/1</id>
<generator url="http://www.movabletype.org/" version="3.17">Movable Type</generator>
<copyright>Copyright (c) 2009, gluck</copyright>
<entry>
<title>Performance problems in ConcurrentHashMap vs synchronized HashMap</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2009/06/performance_pro.html" />
<modified>2009-06-26T09:26:47Z</modified>
<issued>2009-06-26T08:37:26Z</issued>
<id>tag:gregluck.com,2009:/blog/1.173</id>
<created>2009-06-26T08:37:26Z</created>
<summary type="text/plain">In Ehcache 1.6, HashMap was replaced with ConcurrentHashmap with statistical sampling for eviction. Having completed 1.6 and released it there were a few surprises along the way with ConcurrentHashMap performance. PUT and GET performance There is some existing material online...</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Java</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[In Ehcache 1.6, HashMap was replaced with ConcurrentHashmap with statistical sampling for eviction.
Having completed 1.6 and released it there were a few surprises along the way with ConcurrentHashMap performance.

<h2>PUT and GET performance</h2>
There is some existing material online about ConcurrentHashMap versus HashMap performance, notably <a href="http://www.informit.com/guides/content.aspx?g=java&seqNum=246">http://www.informit.com/guides/content.aspx?g=java&seqNum=246</a>.
This article finds that ConcurrentHashMap puts are slower than HashMap when the map gets large: for a map of 1 million objects fully population took three times longer than HashMap for a single threaded scenario. However once you get to multi-threaded scenarios, you need to put synchonrization around HashMap. For those few of you in doubt as to this, email me your HashMap usage I will send you back a multi-threaded test that turns your computer into a fan heater (i.e. 100% infinite loop in the CPUs) in about 30 seconds. The cost of synchronization grows as you add concurrency. Put and Get work well with ConcurrentHashMap in multi-threaded scenarios.

<h2>Iterate Performance</h2>
iterate in ConcurrentHashMap is a lot slower than it is in HashMap and get worse as the map size gets larger. See <a href="http://ehcache.sourceforge.net/xref-test/net/sf/ehcache/CacheTest.html#1886">CacheTest#testConcurrentReadWriteRemoveLFU</a>. For my testing scenarios, which uses 57 threads doing a majority of gets but doing other operations with a variety of map sizes, we get:
<pre>
      * With iterator:
      * 1.6 with 100,000 store size: puts take 45ms. keySet 7ms
      * 1.6 with 1000,000 store size: puts take 381ms. keySet 7ms
      * 1,000,000 - using FastRandom (j.u.Random was dog slow)
      * INFO: Average Get Time for 2065131 observations: 0.013553619 ms
      * INFO: Average Put Time for 46404 obervations: 0.1605034 ms
      * INFO: Average Remove Time for 20515 obervations: 0.1515964 ms
      * INFO: Average Remove All Time for 0 observations: NaN ms
      * INFO: Average keySet Time for 198 observations: 0.0 ms
      * 9999 - using iterator
      * INFO: Average Get Time for 4305030 observations: 0.006000423 ms
      * INFO: Average Put Time for 3216 obervations: 0.92008704 ms
      * INFO: Average Remove Time for 5294 obervations: 0.048545524 ms
      * INFO: Average Remove All Time for 0 observations: NaN ms
      * INFO: Average keySet Time for 147342 observations: 0.5606073 ms
      * 10001 - using FastRandom
      * INFO: Average Get Time for 4815249 observations: 0.005541354 ms
      * INFO: Average Put Time for 5186 obervations: 0.49826455 ms
      * INFO: Average Remove Time for 129163 obervations: 0.015120429 ms
      * INFO: Average Remove All Time for 0 observations: NaN ms
      * INFO: Average keySet Time for 177342 observations: 0.500733 ms
      * 4999 - using iterator
      * INFO: Average Get Time for 4317409 observations: 0.0061599445 ms
      * INFO: Average Put Time for 2708 obervations: 1.0768094 ms
      * INFO: Average Remove Time for 17664 obervations: 0.11713089 ms
      * INFO: Average Remove All Time for 0 observations: NaN ms
      * INFO: Average keySet Time for 321180 observations: 0.26723954 ms
      * 5001 - using FastRandom
      * INFO: Average Get Time for 3203904 observations: 0.0053447294 ms
      * INFO: Average Put Time for 152905 obervations: 0.056616854 ms
      * INFO: Average Remove Time for 737289 obervations: 0.008854059 ms
      * INFO: Average Remove All Time for 0 observations: NaN ms
      * INFO: Average keySet Time for 272898 observations: 0.3118601 ms
</pre>
In summary, with 1 million objects in the map a put to Ehcache using iterate for eviction, takes 381ms! 
<p/>
As a result I have used an alternative to iteration using an algorithm called FastRandom. The result is 0.16 ms, 2,300 times faster!
<p/>
For very small maps, ConcurrentHashMap iteration is quite quick. From experimental testing in Ehcache 1.6 we use iteration up to 5000 entries and FastRandom for sizes above that.
<h2>size() performance</h2>
Thought not as bad as iteration I have noted size as slow in ConcurrentHashMap compared to HashMap. In Ehcache 1.6 we limit the the usage of size(). 

<h2>Recommendations</h2>
If you using ConcurrentHashMap and using more that get/put, test the performance. It may be far, far worse than you were expecting.
<p/>
To give ConcurrentHashMap the best chance of optimisation remember to set the size and expected concurrency when you create it. In ehcache we set the size to the exact size configured for the cache, and we set concurrency to 100 threads. ]]>

</content>
</entry>
<entry>
<title>Ehcache Server in the Cloud </title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2009/06/ehcache_server_1.html" />
<modified>2009-06-19T00:34:42Z</modified>
<issued>2009-06-17T03:02:02Z</issued>
<id>tag:gregluck.com,2009:/blog/1.172</id>
<created>2009-06-17T03:02:02Z</created>
<summary type="text/plain">I am seriously impressed with Amazon&apos;s cloud offering. You get a pick list of virtual machines of different sizes, a CDN, monitoring with elastic forking of new instances, fixed IPs if required, S3, attachable storage and the ability to release...</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Social Commentary</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[I am seriously impressed with Amazon's cloud offering. You get a pick list of virtual machines of different sizes, a CDN, monitoring with elastic forking of new instances, fixed IPs if required, S3, attachable storage and the ability to release software as .amis for easy deployment, map-reduce with Hadoop, load balancing and a payment service. 
<p/>
Each of these is configurable via a RESTful web service. Each one has command-line tools that interact with the web services which you can easily script. And I can see that the new <a href="https://console.aws.amazon.com">https://console.aws.amazon.com</a> management console will bring this together into an easy to use package. Right now there is a tab for EC2 and another for Map-Reduce. Give it a few more months and I can see this populated with tabs for the other services. 
<p/>
<h3>Ehcache Server AMI</h3> 
I love EC2 so much that I decided to create an Amazon Machine Image (AMI) for Ehcache Server. It is marked public and is available for anyone to use. I see it being used in two ways:
<ul>
<li>To quickly try out and demo Ehcache Server. If you have an EC2 account you can be up and running in less than a minute.
<li>As an example of how to deploy Ehcache Server. The AMI comes with an init.d script for service control and ipchains rules mapping ports 80 and 81. You can use it as a template to create your own AMI with your own cache configuration.
</ul>
<h3>Getting Started</h3> 
<ol>
<li>Create a new virtual machine. Select ami-3512f45c from the Community AMIs tab. Select a security configuration and a machine size (small is fine) and start it up. Ehcache Server will start automatically.</li>
<li>To test it, hit it with http://amazon_instance_address/ehcache/rest/sampleCache1. From there, try writing a client. See the <a href="http://ehcache.sourceforge.net/documentation/cache_server.html">Cache Server</a> documentation for sample client code in several languages.</li>
<li>To make configuration changes log into your machine. Ehcache Server is insatalled in   /root/ehcache-server-0.7.</li>
</ol>
<h3>Video Tutorial</h3>
I have put all this in a <a href="http://screencast.com/t/AN1ctzdd">video tutorial</a>. 
]]>

</content>
</entry>
<entry>
<title>The Limitations of Google App Engine</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2009/06/the_limitations.html" />
<modified>2009-06-16T10:55:50Z</modified>
<issued>2009-06-16T10:05:57Z</issued>
<id>tag:gregluck.com,2009:/blog/1.171</id>
<created>2009-06-16T10:05:57Z</created>
<summary type="text/plain">I have a very simple test application up on Google App Engine. See gregrluckapphelloworld.appspot.com. 80MB heap limit Go to gregrluckapphelloworld.appspot.com. Each time you hit is exactly 10MB gets added to Ehcache in-process cache. This is an intentiontal memory leak designed...</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Java</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[I have a very simple test application up on Google App Engine. See <a href="http://gregrluckapphelloworld.appspot.com/">gregrluckapphelloworld.appspot.com</a>.

<h3>80MB heap limit</h3>
Go to <a href="http://gregrluckapphelloworld.appspot.com/">gregrluckapphelloworld.appspot.com</a>. Each time you hit is exactly 10MB gets added to Ehcache in-process cache. This is an intentiontal memory leak designed to find out how much you stick in the heap.
<br/>

The answer is around 80MB. I suspect, taking Jetty into account that there is an -Xmx100m setting in play.

<h3>Crashed sites do not recover immediately or start a new instance.</h3>
When you get an OutOfMemory error the site is cooked. There should be some monitoring that notices and takes it down. That is not the case.
<br/>
I have a wget script which, every 30 seconds, does <pre>while true; do wget "http://gregrluckapphelloworld.appspot.com/"; sleep 30;  done;</pre>

The answer is that the dead site stays down for 5 minutes (10 repetitions of my script). And no new instance gets fired up. Your whole site is down.

<h3>Static content is not distributed through the Google CDN</h3>
On the page I put an image. I did not configure it as static. I downloaded it and got the IP 74.125.19.141 which is in Mountain View, California.

I then marked the images as static in appengine-web-app and redeployed.

There was no effect on the serving location or speed of download.

It may be that the files are served from the static content location

You would expect this to be distributed via Google's CDN.

Here is the header you get from the static content servers.
<pre>
HTTP/1.0 200 OK
  Date: Tue, 16 Jun 2009 09:47:01 GMT
  Expires: Tue, 16 Jun 2009 09:57:01 GMT
  Cache-Control: public, max-age=600
  Content-Type: image/jpeg
  Server: Google Frontend
  Content-Length: 237952
  Connection: Keep-Alive
</pre>

Another interesting thing - cache expiry is set to 10 minutes. A CDN will normally set the TTL longer and rely on a technique such as resource renaming to overcome browser cache issues.

<h3>Conclusion</h3>
None of this is good. The first is a very serious limitation. The last two are killers for running a production app. Hopefully Google will fix these things.]]>

</content>
</entry>
<entry>
<title>Ehcache 1.6.0 is now compatible with Google App Engine</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2009/06/ehcache_160_is.html" />
<modified>2009-06-16T04:20:47Z</modified>
<issued>2009-06-15T23:37:56Z</issued>
<id>tag:gregluck.com,2009:/blog/1.170</id>
<created>2009-06-15T23:37:56Z</created>
<summary type="text/plain">The forthcoming Ehcache 1.6.0 is compatible and works with Google App Engine. You can get it now from ehcache snapshots. Google App Engine provides a constrained runtime which restricts networking, threading and file system access. All features of Ehcache can...</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Java</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[The forthcoming Ehcache 1.6.0 is compatible and works with Google App Engine. You can get it now from ehcache <a href="http://oss.sonatype.org/content/repositories/sourceforge-snapshots/net/sf/ehcache/">snapshots</a>.

Google App Engine provides a constrained runtime which restricts networking, threading and file system access. All features of Ehcache can be used except for the DiskStore and replication. Having said that, there are workarounds for these limitations. 

<h3>Why use Ehcache with Google App Engine?</h3>

Ehcache cache operations take a few µs, versus around 60ms for Google's provided client-server cache   memcacheg (as reported on cloudstatus.com). Because it uses way less resources, it is also cheaper.
You can also store non-Serializable objects in it. And finally there is the rich Ehcache API that you can leverage.
<h3>Recipes</h3>
<h4>Setting up Ehcache as a local cache in front of memcacheg</h4>
The idea here is that your caches are set up in a cache hierarchy. Ehcache sits in front and memcacheg behind. Combining the two lets you elegantly work around limitations imposed by Googe App Engine. You get the benefits of the µs speed of Ehcache together with the umlimited size of memcached.

Ehcache contains the hooks to easily do this.

To update memcached, use a CacheEventListener .

To search against memcacheg on a local cache miss, use cache.getWithLoader() together with a CacheLoader for memcacheg.

<h4>Using memcacheg in place of a DiskStore</h4>
In the CacheEventListener , ensure that when notifyElementEvicted() is called, which it will be when a put exceeds the MemoryStore's capacity, that the key and value are put into memcacheg.

<h4>Distributed Caching</h4>
Configure all notifications in CacheEventListener to proxy throught to memcacheg.

Any work done by one node can then be shared by all others, with the benefit of local caching of frequently used data.

<h4>Dynamic Web Content Caching</h4>
Google App Engine provides acceleration for files declared static in appengine-web.xml.

e.g.

    <static-files>
        <include path="/**.png" />
        <exclude path="/data/**.png" />
    </static-files>

You can get acceleration for dynamic files using Ehcache's caching filters as you usually would.

<h3>Getting Started</h3>
To get started see the <a href="http://ehcache.sourceforge.net/documentation/googleappengine.html">Ehcache with Google App Engine HowTo</a>.]]>

</content>
</entry>
<entry>
<title>The Role of Caching in Large Scale Architecture</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2009/06/the_role_of_cac.html" />
<modified>2009-06-15T22:39:48Z</modified>
<issued>2009-06-15T22:21:43Z</issued>
<id>tag:gregluck.com,2009:/blog/1.169</id>
<created>2009-06-15T22:21:43Z</created>
<summary type="text/plain">I just published an article on The Role of Caching in Large Scale Architecture on DZone....</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Open Source</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[I just published an article on <a href="http://architects.dzone.com/articles/role-caching-large-scale">The Role of Caching in Large Scale Architecture</a> on DZone. 

]]>

</content>
</entry>
<entry>
<title>New ehcache (and SourceForge) Maven repo on oss.sonatype.org</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2009/05/anyone_with_a_p.html" />
<modified>2009-05-09T07:59:10Z</modified>
<issued>2009-05-09T02:08:44Z</issued>
<id>tag:gregluck.com,2009:/blog/1.168</id>
<created>2009-05-09T02:08:44Z</created>
<summary type="text/plain">Anyone with a project on SourceForge who does Maven knows how poorly it supports maven repositories.You can set up repos in the Apache virtual for your project, but you are limited to 100MB. That gets chewed up very fast.Secondly, about...</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Java</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[Anyone with a project on SourceForge who does Maven knows how poorly it supports maven repositories.<div><br></div><div>You can set up repos in the Apache virtual for your project, but you are limited to 100MB. That gets chewed up very fast.</div><div>Secondly, about 6 months ago they revoked ssh access. The result is that the scp wagon cannot create directories. (On a side note, the site deploy is similarly affected - it can scp the file to SourceForge but cannot unzip.) My workaround for this problem has been very frustrating. I do a deploy, which fails, but tells me what directories it was trying to create. Then I sftp to SourceForge and create the directories, then run deploy again. This is such a pain that I have given up deploying snapshots, which then hurts my users.</div><div><br></div><div>Now when it comes to deploying to the Central repo I have set up with them a sync for the ehcache artifacts on SourceForge. That works fine. However recently I needed to do an update to jsr107cache, the draft API for JCACHE. This one is not synced. I have been waiting a month plus for action on the manual JIRA upload process to get that deployed to central, the result being that someone has logged a bug against a the ehcache-jcache module saying there is no jsr107cache. Now it is available on my SourceForge repo but that takes more work for people to figure out.</div><div><br></div><div>So, in summary, SourceForge is not doing a good Maven job. As a past SourceForge project of the month, I thought I should try to get them to fix things. The last thing I want to do is to move my project, with all the hassle that entails. One thing I like about SourceForge is that you retain complete control over the projects you own. There is no benevolent dictator who can sweep in and take over your project. Ross Turk of SourceForge has been quite responsive to my suggestions, but I think they have a lot of projects to manage and Maven is a Java thing. Java is just one of the many languages there projects are written in.</div><div><br></div><div>I have now taken up an offer from Jason Van Zyl for free hosting of my primary repository at <a id="a3wu" href="http://oss.sonatype.org" title="http://oss.sonatype.org">http://oss.sonatype.org</a>. It is synced with central, so my jsr107cache problems are over. No distribution problems either.</div><div><br></div><div><div><span style="font-family: 'Courier New';">&nbsp;&lt;distributionManagement&gt;</span></div><div><span style="font-family: 'Courier New';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&lt;repository&gt;</span></div><div><span style="font-family: 'Courier New';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;id&gt;sourceforge-releases&lt;/id&gt;</span></div><div><span style="font-family: 'Courier New';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;name&gt;Sourceforge Release Repository&lt;/name&gt;</span></div><div><span style="font-family: 'Courier New';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;url&gt;http://oss.sonatype.org/content/repositories/sourceforge-releases&lt;/url&gt;</span></div><div><span style="font-family: 'Courier New';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&lt;/repository&gt;</span></div><div><span style="font-family: 'Courier New';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&lt;snapshotRepository&gt;</span></div><div><span style="font-family: 'Courier New';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;id&gt;sourceforge-snapshots&lt;/id&gt;</span></div><div><span style="font-family: 'Courier New';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;name&gt;Sourceforge Snapshot Repository&lt;/name&gt;</span></div><div><span style="font-family: 'Courier New';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;url&gt;http://oss.sonatype.org/content/repositories/sourceforge-snapshots&lt;/url&gt;</span></div><div><span style="font-family: 'Courier New';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&lt;/snapshotRepository&gt;</span></div><div><span style="font-family: 'Courier New';">&nbsp;&nbsp;&lt;/distributionManagement&gt;</span></div><div><br></div><div>I have already started deploying snapshots to this repo.</div><div><br></div><div>The full contents of the old repositories at http://ehcache.sf.net/repository and http://ehcache.sf.net/snapshotrepository have been migrated to sonatype by the guys there. I have deleted the old repository to avoid confusion.</div><div><br></div><div>At sonatype my stuff lives in a SourceForge repository. Any other SourceForge based projects wishing to host their Maven repos there should contact the guys at Sonatype, as this will be simple for them to set up.</div><div><br></div><div>oss.sonatype.org runs on <a id="o3zc" href="http://nexus.sonatype.org/" title="Nexus">Nexus</a>, a new Maven Repository Manager ("MRM"). It makes a lot of sense to use an MRM inside your company. While a dumb Apache directory works, there is so much more you can do with an MRM. Searching, proxying externals and providing developer friendly metadata are top of my list. Nexus is dual sourced, with a community edition giving most of what you want, and things like LDAP for security available in the licensed version. And of course, uses ehcache :).&nbsp;</div><div><br></div><div>Using a smart primary repo, which is then synced to central is better for quality too. As Jason says,&nbsp;</div><div><br></div><div><i>"i</i><span style="font-family: Helvetica"><font size="2"><i>f we could get enough projects to use the Nexus gateway then we can really start taking real measures to have signatures, sources, javadocs and even check that transitive closures are intact. Basically prevent any shit from getting into the central repository and making it easier for projects to get artifacts to central."</i></font><span style="font-family: Verdana"><font size="2"><i>&nbsp;&nbsp;</i></font></span></span></div><div><br></div><div><br></div></div><br>]]>

</content>
</entry>
<entry>
<title>Ehcache 1.6 2 Orders of Magnitude Faster</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2009/02/i_have_been_wai.html" />
<modified>2009-02-24T23:38:51Z</modified>
<issued>2009-02-21T08:55:40Z</issued>
<id>tag:gregluck.com,2009:/blog/1.167</id>
<created>2009-02-21T08:55:40Z</created>
<summary type="text/plain">I have been waiting for enough people to move to Java 5 to mandate it as a minimum standard for ehcache. At JavaOne 2008 I found out that a lot of people were still to make the move. Now that...</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Java</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[I have been waiting for enough people to move to Java 5 to mandate it as a minimum standard for ehcache. At JavaOne 2008 I found out that a lot of people were still to make the move. Now that we are in 2009 I have decided to move to Java 5. As part of this I have done a general cleanup of the core. I can now retire backport-concurrent which has served the project well (thanks guys) and other dependencies. Ehcache-1.6 core has no dependencies.
<div>
  <br>
</div>
<div>
  I decided that with the improvements in concurrency support that have come along, it was time to move beyond the use of synchronized. Years ago I adopted striped locking on BlockingCache which gave amazing results but I left the core pretty much as it was. The rework adopts some new goodness in Java 5 such as CopyOnWriteArray and ConcurrentHashMap. Having said that there is nothing in Java 5 for eviction, so the new work relies heavily on some excellent contributions to provide performance for caching application that is not available in Java 5.
</div>
<div>
  <br>
</div>
<div>
  <div style="MARGIN-TOP:0px; MARGIN-BOTTOM:0px">
    On my own concurrency tests, which use 70 threads simulating a typical load against a single cache, I get the following improvements in ehcache-1.6 over ehcache-1.5. (Note 70 are just for that cache. Ehcache typically has many caches, so this translates to a production system with thousands of threads against all caches)
  </div>
  <div style="MARGIN-TOP:0px; MARGIN-BOTTOM:0px">
    <br>
  </div>
  <div style="MARGIN-TOP:0px; MARGIN-BOTTOM:0px">
    <div style="MARGIN-TOP:0px; MARGIN-BOTTOM:0px">
      <table border="0" cellpadding="3" cellspacing="0" class="zeroBorder" id="n4e-" style="FONT-SIZE:1em; BORDER-TOP-WIDTH:1px; BORDER-RIGHT-WIDTH:1px; BORDER-BOTTOM-WIDTH:1px; BORDER-LEFT-WIDTH:1px; border-top-style:dotted; border-right-style:dotted; border-bottom-style:dotted; border-left-style:dotted; border-top-COLOR:gray; border-right-COLOR:gray; border-bottom-COLOR:gray; border-left-COLOR:gray">
        <tbody>
        <tr style="TEXT-ALIGN:left">
          <td style="BORDER-TOP-WIDTH:1px; BORDER-RIGHT-WIDTH:1px; BORDER-BOTTOM-WIDTH:1px; BORDER-LEFT-WIDTH:1px; border-top-style:dotted; border-right-style:dotted; border-bottom-style:dotted; border-left-style:dotted; border-top-COLOR:gray; border-right-COLOR:gray; border-bottom-COLOR:gray; border-left-COLOR:gray" width="50%">
            <b>Operation</b>
          </td>
          <td style="BORDER-TOP-WIDTH:1px; BORDER-RIGHT-WIDTH:1px; BORDER-BOTTOM-WIDTH:1px; BORDER-LEFT-WIDTH:1px; border-top-style:dotted; border-right-style:dotted; border-bottom-style:dotted; border-left-style:dotted; border-top-COLOR:gray; border-right-COLOR:gray; border-bottom-COLOR:gray; border-left-COLOR:gray" width="50%">
            <b>Number of Times Faster<br>
            Than Ehcache-1.5.0</b>
          </td>
        </tr>
        <tr style="TEXT-ALIGN:left">
          <td style="BORDER-TOP-WIDTH:1px; BORDER-RIGHT-WIDTH:1px; BORDER-BOTTOM-WIDTH:1px; BORDER-LEFT-WIDTH:1px; border-top-style:dotted; border-right-style:dotted; border-bottom-style:dotted; border-left-style:dotted; border-top-COLOR:gray; border-right-COLOR:gray; border-bottom-COLOR:gray; border-left-COLOR:gray" width="50%">
            get
          </td>
          <td style="BORDER-TOP-WIDTH:1px; BORDER-RIGHT-WIDTH:1px; BORDER-BOTTOM-WIDTH:1px; BORDER-LEFT-WIDTH:1px; border-top-style:dotted; border-right-style:dotted; border-bottom-style:dotted; border-left-style:dotted; border-top-COLOR:gray; border-right-COLOR:gray; border-bottom-COLOR:gray; border-left-COLOR:gray" width="50%">
            92.5 times faster
          </td>
        </tr>
        <tr style="TEXT-ALIGN:left">
          <td style="BORDER-TOP-WIDTH:1px; BORDER-RIGHT-WIDTH:1px; BORDER-BOTTOM-WIDTH:1px; BORDER-LEFT-WIDTH:1px; border-top-style:dotted; border-right-style:dotted; border-bottom-style:dotted; border-left-style:dotted; border-top-COLOR:gray; border-right-COLOR:gray; border-bottom-COLOR:gray; border-left-COLOR:gray" width="50%">
            put
          </td>
          <td style="BORDER-TOP-WIDTH:1px; BORDER-RIGHT-WIDTH:1px; BORDER-BOTTOM-WIDTH:1px; BORDER-LEFT-WIDTH:1px; border-top-style:dotted; border-right-style:dotted; border-bottom-style:dotted; border-left-style:dotted; border-top-COLOR:gray; border-right-COLOR:gray; border-bottom-COLOR:gray; border-left-COLOR:gray" width="50%">
            30 times faster
          </td>
        </tr>
        <tr style="TEXT-ALIGN:left">
          <td style="BORDER-TOP-WIDTH:1px; BORDER-RIGHT-WIDTH:1px; BORDER-BOTTOM-WIDTH:1px; BORDER-LEFT-WIDTH:1px; border-top-style:dotted; border-right-style:dotted; border-bottom-style:dotted; border-left-style:dotted; border-top-COLOR:gray; border-right-COLOR:gray; border-bottom-COLOR:gray; border-left-COLOR:gray" width="50%">
            remove
          </td>
          <td style="BORDER-TOP-WIDTH:1px; BORDER-RIGHT-WIDTH:1px; BORDER-BOTTOM-WIDTH:1px; BORDER-LEFT-WIDTH:1px; border-top-style:dotted; border-right-style:dotted; border-bottom-style:dotted; border-left-style:dotted; border-top-COLOR:gray; border-right-COLOR:gray; border-bottom-COLOR:gray; border-left-COLOR:gray" width="50%">
            48 times faster
          </td>
        </tr>
        <tr style="TEXT-ALIGN:left">
          <td style="BORDER-TOP-WIDTH:1px; BORDER-RIGHT-WIDTH:1px; BORDER-BOTTOM-WIDTH:1px; BORDER-LEFT-WIDTH:1px; border-top-style:dotted; border-right-style:dotted; border-bottom-style:dotted; border-left-style:dotted; border-top-COLOR:gray; border-right-COLOR:gray; border-bottom-COLOR:gray; border-left-COLOR:gray" width="50%">
            removeAll
          </td>
          <td style="BORDER-TOP-WIDTH:1px; BORDER-RIGHT-WIDTH:1px; BORDER-BOTTOM-WIDTH:1px; BORDER-LEFT-WIDTH:1px; border-top-style:dotted; border-right-style:dotted; border-bottom-style:dotted; border-left-style:dotted; border-top-COLOR:gray; border-right-COLOR:gray; border-bottom-COLOR:gray; border-left-COLOR:gray" width="50%">
            80 times faster
          </td>
        </tr>
        <tr style="TEXT-ALIGN:left">
          <td style="BORDER-TOP-WIDTH:1px; BORDER-RIGHT-WIDTH:1px; BORDER-BOTTOM-WIDTH:1px; BORDER-LEFT-WIDTH:1px; border-top-style:dotted; border-right-style:dotted; border-bottom-style:dotted; border-left-style:dotted; border-top-COLOR:gray; border-right-COLOR:gray; border-bottom-COLOR:gray; border-left-COLOR:gray" width="50%">
            keySet
          </td>
          <td style="BORDER-TOP-WIDTH:1px; BORDER-RIGHT-WIDTH:1px; BORDER-BOTTOM-WIDTH:1px; BORDER-LEFT-WIDTH:1px; border-top-style:dotted; border-right-style:dotted; border-bottom-style:dotted; border-left-style:dotted; border-top-COLOR:gray; border-right-COLOR:gray; border-bottom-COLOR:gray; border-left-COLOR:gray" width="50%">
            30 times faster
          </td>
        </tr>
        </tbody>
      </table>
      <br>
    </div>
  </div>
  <div style="MARGIN-TOP:0px; MARGIN-BOTTOM:0px">
    <br>
  </div>
  <div style="MARGIN-TOP:0px; MARGIN-BOTTOM:0px">
    Manik Surtani maintains a cache performance benchmark tool. Using that I have added ehcache-1.6. It shows dramatically the performance increases in Ehcache-1.6.
  </div>
  <div style="MARGIN-TOP:0px; MARGIN-BOTTOM:0px">
    <br>
  </div>
  <div style="MARGIN-TOP:0px; MARGIN-BOTTOM:0px">
    For those with less than perfect eyesight, the second column, which is too short to even have its time printed, is the ehcache-1.6 performance.
  </div>
  <div id="v:0j" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">
    <img src="http://docs.google.com/File?id=agbdcfj3mkdt_27hb44n9dv_b" style="WIDTH:600px; HEIGHT:600px">
  </div>
</div>
<div>
  <br>
</div>
<div>
  <br>
</div>
<div id="q8p_" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">
  <img src="http://docs.google.com/File?id=agbdcfj3mkdt_306skgwxgr_b" style="WIDTH:600px; HEIGHT:600px">
</div>
<div id="q8p_" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">
  What these charts are saying, is that an ehcache, with 25 concurrent threads, is now much faster than it was. The single threaded case it no faster. But caches are not about single threads.
</div>
<div id="q8p_" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">
  Now, in case everyone gets preoccupied on the comparsions between Java caches, here is an old Ehcache versus Memcached chart.
</div>
<div id="q8p_" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">
  <div id="idpt" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">
    <img src="http://docs.google.com/File?id=agbdcfj3mkdt_31cgz5fvg8_b" style="WIDTH:600px; HEIGHT:326px">
  </div><div id="idpt" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">If I redid this chart using ehcache, the barely visible columns for ehcache would completely disappear on this scale.</div><div id="idpt" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">So what is this really saying? An in-process cache, which uses a few tens of CPU operations to access data already held in memory, is much, much, much faster than going out over the network for some data, regardless of how slick the server implementation at the other end is.</div><div id="idpt" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">But I recognise that Memcached is about a different type of caching: massive partitioned caches. The Ehcache project has the Ehcache Server for that, with RESTful and SOAP APIs. The RESTful implementation uses a variety of tricks such as conditional get, the ability to have hardware and software load balancers (think ngnx) perform URI routing, head, HTTP1.1 compression and pipelining plus the goodness of modern NIO Java Web Containers to seriously give memcached a run for its money. I will be doing some performance comparisons between Memcached and Ehcache Server in the near future.</div><div id="idpt" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">What else is next? The above numbers are for MemoryStore based caches. I am also going to give the DiskStore a work over, with lots of suggestions made to me in the last year. Stay tuned.</div><div id="idpt" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">&nbsp;</div><div id="idpt" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px"><br></div>
</div>
<div id="q8p_" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">
  <br>
</div>
<div id="q8p_" style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">
  <br>
</div>
<br>]]>

</content>
</entry>
<entry>
<title>Scala example for accessing Ehcache Server</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2009/01/scala_example_f.html" />
<modified>2009-02-08T01:50:33Z</modified>
<issued>2009-01-20T06:52:24Z</issued>
<id>tag:gregluck.com,2009:/blog/1.166</id>
<created>2009-01-20T06:52:24Z</created>
<summary type="text/plain">A few months ago I was chatting to Brad Clow about the new Ehcache Server. I asked him for an example with Scala. Anyway he just got back to me with what is the smallest program yet for accessing RESTful...</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Open Source</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[<p>A few months ago I was chatting to Brad Clow about the new Ehcache Server. I asked him for an example with Scala. Anyway he just got back to me with what is the smallest program yet for accessing RESTful Ehcache Server.</p>

<p>In a file named ExampleScalaGet.scala:</p>

<pre>
   import java.net.URL
   import scala.io.Source.fromInputStream

   object ExampleScalaGet extends Application {
     val url = new URL("http://localhost:8080/ehcache/rest/sampleCache2/2")
     fromInputStream(url.openStream).getLines.foreach(print)
   }
</pre>

<p>run it with:</p>

<pre><code>scala -e ExampleScalaGet

The program outputs:

 &lt;?xml version="1.0"?&gt;
 &lt;oldjoke&gt;
 &lt;burns&gt;Say &lt;quote&gt;goodnight&lt;/quote&gt;,
 Gracie.&lt;/burns&gt;
 &lt;allen&gt;&lt;quote&gt;Goodnight, 
 Gracie.&lt;/quote&gt;&lt;/allen&gt;
 &lt;applause/&gt;
</code></pre>

<p>If you are on a Mac the easiest way to get scale installed is "sudo port install scala".</p>

<p>The Scala program ways in at 6 lines. Now, let's compare it's tersity with the other languages, all doing a GET and printing the result (See http://ehcache.sourceforge.net/documentation/cache_server.html for the examples). Whitespace lines are not included.</p>

<p>Scala 6 lines, using java.net.URL<br/> 
PHP 6 lines, using curl lib<br/>
Python 3 lines, using urllib2<br/>
Ruby 6 lines, using open-uri<br/>
Java 19 lines, using java.net.HttpUrlConnection, which does a few things before it gives the InputStream as used in the Scala example. <br/></p>

<p>Thanks to Brad for rounding out the examples.</p>

<p>Scala looks very interesting.
Comparing it with the others:</p>

<p>Brad has also blogged about his Scala example here: http://bradclow.blogspot.com/2009/01/scala-example-for-accessing-ehcache.html</p>
]]>

</content>
</entry>
<entry>
<title>REST all and collection resource conventions</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2008/11/rest_all_and_co.html" />
<modified>2008-11-27T09:18:45Z</modified>
<issued>2008-11-27T09:15:10Z</issued>
<id>tag:gregluck.com,2008:/blog/1.165</id>
<created>2008-11-27T09:15:10Z</created>
<summary type="text/plain">Users of ehcache server have been discussing extending the basic CRUD operations of REST with some more advanced methods, such as deleting all elements in a cache with one DELETE operation. You are most welcome to join what has become...</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Java</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[<p>Users of ehcache server have been discussing extending the basic CRUD operations of REST with some more advanced methods, such as deleting all elements in a cache with one DELETE operation.</p>

<p>You are most welcome to join what has become an informative forum thread here: https://sourceforge.net/forum/forum.php?thread_id=2546225&forum_id=322278</p>

<p>So far we have posts from myself, Jim Webber, Brett Dargan and others interested in creating or finding a REST convention for referring to all and specifying means of multi-get, multi-put and multi-delete.</p>]]>

</content>
</entry>
<entry>
<title>mvn glassfish:run</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2008/11/mvn_glassfishru.html" />
<modified>2008-12-19T00:59:55Z</modified>
<issued>2008-11-27T08:58:02Z</issued>
<id>tag:gregluck.com,2008:/blog/1.164</id>
<created>2008-11-27T08:58:02Z</created>
<summary type="text/plain">In April Dave Whitla created a project for a Maven Glassfish Plugin. Kohsuke Kowaguchi joined the project and copied his code in and released it. His focus was V3 Embedded. It supported one goal: run. There was disagreement as to...</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Java</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[<p>In April Dave Whitla created a project for a Maven Glassfish Plugin.<br />
<p/><br />
Kohsuke Kowaguchi joined the project and copied his code in and released it. His focus was V3 Embedded. It supported one goal: run.<br />
<p/><br />
There was disagreement as to the features and the code to use. Dave's plugin was to support a wide range of goals supporting integration of V2 and above into the build process.<br />
<p/><br />
Now to use the convenience name you normally add a pluginGroup:</p>

<pluginGroups>
       <pluginGroup>org.glassfish</pluginGroup> 
       <pluginGroup>org.glassfish.maven.plugin</pluginGroup>
   </pluginGroups>
<p/>
The end result is that we have two plugins called maven-glassfish-plugin which are different, but because they use the special naming of maven-name-plugin, both are invoked with mvn glassfish:goal, causing a namespace conflict.
<p/>
Now when I do mvn glassfish:run I get:
<pre>
 mvn glassfish:run
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'glassfish'.
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Required goal not found: glassfish:run in org.glassfish.maven.plugin:maven-glassfish-plugin:2.1
[INFO] ------------------------------------------------------------------------
</pre>
Until or unless Dave's add a run goal, you can work around it by avoiding Maven's convenience naming conventions and fully qualifying Kohsuke's.

<p>mvn org.glassfish:maven-glassfish-plugin:run</p>

<p><br />
It would be nice for one of Kohsuke, Dave or Byron to sort this out.</p>

<p>My suggestion is for Kohsuke to rename his to maven-glassfish-embedded-plugin.</p>]]>

</content>
</entry>
<entry>
<title>Me:decoded</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2008/11/medecoded_aa_a.html" />
<modified>2008-11-21T03:54:17Z</modified>
<issued>2008-11-21T03:52:44Z</issued>
<id>tag:gregluck.com,2008:/blog/1.163</id>
<created>2008-11-21T03:52:44Z</created>
<summary type="text/plain">Me:decoded I recently had my DNA tested byÂ deCODEme.com.Â  My wife thought I was crazy. The idea was to find out what diseases I was more or less susceptible to, and then use that information, along with more conventional tests, and...</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Social Commentary</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[Me:decoded
<div>
</div>
<div>
  <br>
</div>
<div>
  <br>
</div>
<div>
  I recently had my DNA tested byÂ <a href="http://www.decodeme.com/" id="j85e" title="Decode Me">deCODEme.com</a>.Â 
</div>
<div>
  <br>
</div>
<div>
  <span style="WHITE-SPACE:pre-wrap">My wife thought I was crazy. The idea was to find out what diseases I was more or less susceptible to, and then use</span>
</div>
<div>
  <span style="WHITE-SPACE:pre-wrap">that information, along with more conventional tests, and consultation with my doctor, to create a personalised medicine</span>
</div>
<div>
  <span style="WHITE-SPACE:pre-wrap">preventative plan for myself.</span></div><div><span style="WHITE-SPACE:pre-wrap">  </span>
</div>
<div>
  <span style="WHITE-SPACE:pre-wrap">Think of it in the same way you would regular car servicing. The servicing details depend on the Brand and model of car,</span>
</div>
<div>
  <span style="WHITE-SPACE:pre-wrap">together with how many kms done and whether you did it off road or on road. </span></div><div><span style="WHITE-SPACE:pre-wrap">  </span>
</div>
<div>
  <span style="WHITE-SPACE:pre-wrap">Anyway, I have learnt much of interest, some of which I am disclosing on this blog entry.</span>
</div>
<h3>
  Ancestry
</h3>
<div>
  As you can see from the chart my closest correlation is to the French group, followed by the Orcadian group.
</div>
<div>
  This makes sense: my father's family was originally Flemish and my mother's family Scots. From the spelling
</div>
<div>
  of my mother's name it was likely that we were from the offshore islands. I guess Orcadian is a reference
</div>
<div>
  to the Orkney islands, off the north east coast of Scotland.Â 
</div>
<div>
  <div id="ca9." style="TEXT-ALIGN:left; PADDING-TOP:1em; PADDING-BOTTOM:1em; PADDING-RIGHT:0px; PADDING-LEFT:0px">
    <img src="http://docs.google.com/File?id=agbdcfj3mkdt_25f8zhr6fs_b" style="WIDTH:612px; HEIGHT:377px">
  </div>
</div>
<h3>
  Mitochondrial &amp; Y DNA
</h3>
<div>
  I am a Mitogroup J. The exciting thing about this is that we are long livers, according to a recent study in Nature.
</div>
<div>
  SeeÂ http://www.nature.com/ejhg/journal/v9/n9/abs/5200703a.html
</div>
<div>
  <br>
</div>
<div>
  My Y-Group is also J, but it means something different.
</div>
<div>
  <br><font size="2">
  </font>
</div>
<div>
  <font size="2">Quoting from deCODEme, "Today, the greatest concentration of Y-group J members is found in the Near East, North Africa, and Ethiopia, where up to 30 percent of males belong to this Y-group. The frequency of Y-group J members in Europe is much lower, or close to 3 percent. Members of Y-group J are relatively common among Jewish populations, where about 25 percent belong to this Y-group."Â </font>
</div>
<div>
  <br>
  
</div>
<div>
  Apparently there are clubs for these groups.</div>
<h3>
  Compared With
</h3>
<div>
  One neat thing you can do is compare yourself with people on the record or friends. (Think facebook friends with DNA!).
</div>
<div>
  <br>
  
</div>
<div>
  I do not have any friends yet, but I have compared myself with James Watson and Craig Venter. I am extremely unrelated to James Watson.Â 
</div>
<div>
  For Craig Venter I have low to medium sharing with some very high sharing on the X chromosome. Welcome, distant relative.
</div>
<div>
  <br>
  
</div>
<h3>
  Susceptibilities
</h3>
<div>
  I was rather pleased with my disease susceptibilities. I already knew I had Factor V Leiden Heterozygous, which I have inherited from my mother.
</div>
<div>
  I am at higher risk than 99.8% of the population for DVTs and the like. Because I already knew this, when I was specifically tested for it ten years ago,Â 
</div>
<div>
  I have avoided drinking alcohol or sleeping on flightsÂ for the past ten years.
</div>
<div>
  <br>
  
</div>
<div>
  
  <div style="MARGIN-TOP:0px; MARGIN-BOTTOM:0px">
    One thing I was very happy about, given the heart disease on my father's side (but not my mother's side) is that I Have .87% the risk
  </div>
  <div style="MARGIN-TOP:0px; MARGIN-BOTTOM:0px">
    of the average European male. Given that I am a non-smoker, and do not have Male Metabolic Syndrome, or high blood pressure, I am feeling pretty good about this one.
  </div>
  <div style="MARGIN-TOP:0px; MARGIN-BOTTOM:0px">
    <br>
  </div>
  
</div>
<div>
  For the most part I am pretty happy with what I have found. And for those few things I am at elevated risk of, I can focus more on preventative testing
</div>
<div>
  and lifestyle adjustment. Of course, having an elevated risk needs to be turned into a lifetime risk first. deCODEme do this too.
</div>
<div>
  <br>
  
</div>
<div>
  <b>Improvements</b>
</div>
<div>
  Something I would like to see in future is the ability to add your own environmental factors such as smoking, BMI, age etc to get more accurate lifetime risks.</div><div><br></div><div>And of course, more people to compare with and more disease susceptibilities.</div><div><br></div><div>All considered, I am happy I did this.</div>
<div>
  <br>
  
</div><br>]]>

</content>
</entry>
<entry>
<title>Planes, Trains and Automobiles</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2008/11/planes_trains_a.html" />
<modified>2009-01-20T23:26:17Z</modified>
<issued>2008-11-15T00:14:03Z</issued>
<id>tag:gregluck.com,2008:/blog/1.162</id>
<created>2008-11-15T00:14:03Z</created>
<summary type="text/plain">Ever seen the movie Planes, Trains and Automobiles? Some travelers are caught up in an unbelievable snafu trying to get home for Thanksgiving. Well, Brett Dargan, a colleague, and I had our own version of this over the past two...</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Social Commentary</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[<p>Ever seen the movie <i>Planes, Trains and Automobiles</i>? Some travelers are caught up in an unbelievable snafu trying to get home for Thanksgiving.</p>

<p>Well, Brett Dargan, a colleague, and I had our own version of this over the past two days. We came down to Sydney to run an Architecture Away Day. All went well. We were sitting at the Swiss Grand Resort and Spa looking out over Bondi beach, knocking down beers with the attendees after the event about 5:30pm when the waiter (server for my US readers) pointed out a big storm brewing to the South. I felt the first unease. </p>

<p>Then a few minutes later I received an ominous SMS from Virgin Blue to tell me that my 7pm flight had been delayed.  I rang up Customer Service, but of course several hundred other people were trying to do the same thing, so I gave up after spending 6 minutes in the queue. More beers. Brett then rang up 15 minutes later and got through. We were now on a 9pm flight. So, off to the Cricketer's Arms Hotel in Surrey with Nugget for Tapas and more beers. </p>

<p>Having a good time at the Cricketers Arms. Catching up with some former colleagues and enjoying some great Tapas: Chorizo, Lamb Kofta and Grilled Haloumi, washed down with Pure Blonde low carb beer. Mike Edwards, a fellow drinker mentioned "Great lightning show out there". Sure enough the storm that had been brewing was now coming close and looking bad. So I checked http://bom.gov.au and saw that there was a severe weather warning for Sydney over the next few hours, with heavy rain and damaging winds. </p>

<p>At this point I was beginning to think that it could be a bad night. By now it was time to go to the airport, so we said our goodbyes and went outside - right into a massive rain downpour. We managed to flag a taxi who, when we said the airport for our destination, said no, then drove 20 metres down the road, and then waved to us to get in. The street was a river by now, with 5 cm of water over the asphalt. We both got soaked to our ankles. From there we had an uneventful ride to the airport.</p>

<p>All went well until we got on our plane. We sat and waited, and waited, and waited. Then the steward, who was already looking well harried, made an announcement that a Flight Instrument was broken, and engineers were trying to fix it. This went on for half an hour, after which were deplaned. More waiting at the gate and then it was announced they had a plane for us at the opposite end of the airport at the JetStar terminal. We all trudged through an airport whose shops were closing up down there and eventually got on another plane. For non regular Sydney visitors, note that Sydney has a flight curfew of 11pm. Anyway the we got on, the baggage got loaded and were taxied out and waited to access the runway. And waited. And waited. </p>

<p>By now it was 10:30pm. Then the harried steward came on the Intercom and said that we were waiting for some other flights to land (I guess they take precedence when you get close to the curfew) before we could take off. He mentioned that we would be cutting the curfew close. After that we had regular updates every 5 minutes, as we moved inexorably towards the curfew time. </p>

<p>Now it was 11:02 pm. It was not looking good. Then the captain came on with encouraging news: we were now after curfew, but we had a flight clearance and could take off on the East-West runway out over the ocean. We were waiting for a few other planes.</p>

<p>At this point we allowed to move around the cabin. The harried steward kindly explained that the snafu had started at 3:30pm while the weather was still fine. He blamed short staffed Sydney air traffic controllers. </p>

<p>A few minutes later he came back on to say the cross-winds were too high, and we, along with several other 737s were waiting for them to abate. The larger planes were getting away.</p>

<p>You can guess what happened next. The captain announced the winds were not abating and we were going back to the gate, just as soon as a gate was available, because of course most of the airport and Virgin Blue staff had gone home. 10 minutes later we deplaned into a enclosed gangway. One problem: the door to the airport was locked. We sat in there like rats in a trap for a quarter hour before we were finally let out. </p>

<p>Back at the gate we sat around and waited, and waited, while Virgin Blue figure out what we all going to do. In the end they announced we would need to sleep at the airport, because "the delay was weather related". I guess it was apart from the broken plane which caused our particular problem, which was in their control, and the airport issues which were not.</p>

<p>At this point Brett and I ran for a taxi to try and get a local hotel. Three hotels later I realised that other flights had already been bounced by the curfew ahead of us. We ended up back in the city at the Grace Hotel. The Night Auditor was checking us, and a horde of other stranded travelers in. I imagine this scene was being played out all across the city.</p>

<p>So, as I write this entry, I am sitting at Gate 39 at Sydney airport for a 12 noon flight. It was just announced over the intercom that our flight would be delayed due to our cabin crew not having yet arrived...</p>]]>

</content>
</entry>
<entry>
<title>Ehcache Server Technical Session Video </title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2008/11/ehcache_server.html" />
<modified>2008-11-07T07:58:30Z</modified>
<issued>2008-11-07T07:55:23Z</issued>
<id>tag:gregluck.com,2008:/blog/1.161</id>
<created>2008-11-07T07:55:23Z</created>
<summary type="text/plain">I gave a talk today at the Glassfish V3 Prelude Launch Event. Ehcache Server uses Glassfish for its self contained cache server. You can watch the video of the session here....</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Java</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[I gave a talk today at the Glassfish V3 Prelude Launch Event. Ehcache Server uses Glassfish for its self contained cache server. You can watch the video of the session <a href="http://www.ustream.tv/recorded/843949">here</a>.]]>

</content>
</entry>
<entry>
<title>Exit Reality is in a Different Reality - Windows Only</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2008/09/exit_reality_is.html" />
<modified>2009-03-16T08:16:47Z</modified>
<issued>2008-09-18T10:40:28Z</issued>
<id>tag:gregluck.com,2008:/blog/1.160</id>
<created>2008-09-18T10:40:28Z</created>
<summary type="text/plain">I thought we saw the end of this nonsense years ago. But no. Exit Reality is Windows only. If you are on a Mac, http://q.exitreality.com/relaunch.html will tell you &quot;Mac users are able to experience full hardware accelerated 3D by running...</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Open Source</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[<p>I thought we saw the end of this nonsense years ago. But no. </p>

<p>Exit Reality is Windows only. If you are on a Mac, http://q.exitreality.com/relaunch.html will tell you</p>

<p>"Mac users are able to experience full hardware accelerated 3D by running Windows with either:<br />
 (using OpenGL) or BootCamp  (using Direct3D)"</p>

<p>In other words, Mac users should run Windows!</p>

<p>Insultingly, they then go on to say on their "Platform page"</p>

<p>"ExitReality 3D platform has been built in open standards and complies with International Standards Organisation regulations (ISO) and W3C. It is a free 3D platform that anyone can use to set up their own virtual world on their website.</p>

<p>The ExitReality 3D platform has been developed for all internet users. Any web page can be viewed and interacted with in 3D, and anyone can create their own virtual world using ExitReality."</p>

<p>Any platform means Windows and anyone means a Windows user. I can only say they are in a Different Reality.</p>

<p>I haven't been this annoyed for years. Almost enough to lodge a False and Misleading Advertising Complaint with the ACCC.</p>]]>

</content>
</entry>
<entry>
<title>Example RESTful Java client for Ehcache</title>
<link rel="alternate" type="text/html" href="http://gregluck.com/blog/archives/2008/09/example_restful.html" />
<modified>2008-11-21T01:06:12Z</modified>
<issued>2008-09-11T02:44:00Z</issued>
<id>tag:gregluck.com,2008:/blog/1.159</id>
<created>2008-09-11T02:44:00Z</created>
<summary type="text/plain">Rick Bryant sent me some sample code he wrote which shows how to use the RESTful Cache Server from Java. Thanks Rick. To use the sample just fire up the cache server: startup.sh and then run the following Java code....</summary>
<author>
<name>gluck</name>

<email>gluck@gregluck.com</email>
</author>
<dc:subject>Java</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://gregluck.com/blog/">
<![CDATA[<p>Rick Bryant sent me some sample code he wrote which shows how to use the RESTful Cache Server from Java.  Thanks Rick. To use the sample just fire up the cache server: startup.sh  and then run the following Java code.</p>

<pre>
package samples;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * A simple example Java client which uses the built-in java.net.URLConnection.
 *
 * @author BryantR
 * @author Greg Luck
 */
public class ExampleJavaClient {

    private static String TABLE_COLUMN_BASE =
            "http://localhost:8080/ehcache/rest/tableColumn";
    private static String TABLE_COLUMN_ELEMENT =
            "http://localhost:8080/ehcache/rest/tableColumn/1";

    /**
     * Creates a new instance of EHCacheREST
     */
    public ExampleJavaClient() {
    }

    public static void main(String[] args) {
        URL url;
        HttpURLConnection connection = null;
        InputStream is = null;
        OutputStream os = null;
        int result = 0;
        try {
            //create cache
            URL u = new URL(TABLE_COLUMN_BASE);
            HttpURLConnection urlConnection = (HttpURLConnection) u.openConnection();
            urlConnection.setRequestMethod("PUT");

            int status = urlConnection.getResponseCode();
            System.out.println("Status: " + status);
            urlConnection.disconnect();

            //get cache
            url = new URL(TABLE_COLUMN_BASE);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            is = connection.getInputStream();
            byte[] response1 = new byte[4096];
            result = is.read(response1);
            while (result != -1) {
                System.out.write(response1, 0, result);
                result = is.read(response1);
            }
            if (is != null) try {
                is.close();
            } catch (Exception ignore) {
            }
            System.out.println("reading cache: " + connection.getResponseCode()
                    + " " + connection.getResponseMessage());
            if (connection != null) connection.disconnect();

            //create entry
            url = new URL(TABLE_COLUMN_ELEMENT);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("Content-Type", "text/plain");
            connection.setDoOutput(true);
            connection.setRequestMethod("PUT");
            connection.connect();
            String sampleData = "ehcache is way cool!!!";
            byte[] sampleBytes = sampleData.getBytes();
            os = connection.getOutputStream();
            os.write(sampleBytes, 0, sampleBytes.length);
            os.flush();
            System.out.println("result=" + result);
            System.out.println("creating entry: " + connection.getResponseCode()
                    + " " + connection.getResponseMessage());
            if (connection != null) connection.disconnect();

            //get entry
            url = new URL(TABLE_COLUMN_ELEMENT);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            is = connection.getInputStream();
            byte[] response2 = new byte[4096];
            result = is.read(response2);
            while (result != -1) {
                System.out.write(response2, 0, result);
                result = is.read(response2);
            }
            if (is != null) try {
                is.close();
            } catch (Exception ignore) {
            }
            System.out.println("reading entry: " + connection.getResponseCode()
                    + " " + connection.getResponseMessage());
            if (connection != null) connection.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (os != null) try {
                os.close();
            } catch (Exception ignore) {
            }
            if (is != null) try {
                is.close();
            } catch (Exception ignore) {
            }
            if (connection != null) connection.disconnect();
        }
    }
}
</pre>
]]>

</content>
</entry>

</feed>