<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5591335197619669570</id><updated>2012-02-16T19:19:47.954-08:00</updated><category term='ehcache'/><category term='data structures'/><category term='heap'/><category term='Eclipse'/><category term='NoGC'/><category term='Performance Tuning'/><category term='gc'/><category term='high availability'/><category term='big memory'/><category term='maven'/><category term='nosql'/><category term='elastic caching'/><category term='Clustered Events'/><category term='Terracotta'/><category term='caching'/><category term='Java'/><category term='bigmemory'/><title type='text'>Javasmith</title><subtitle type='html'>musings about Java and Technology</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-9076686722919737804</id><published>2012-01-28T22:41:00.000-08:00</published><updated>2012-01-29T18:49:18.986-08:00</updated><title type='text'>Mockito is just awesomeness</title><content type='html'>Last week I ventured into making some enhancements into a project that is completely unknown to me. I see unit tests as my writ of passage before I can checkin any code into a project new to me --not to say I should ever checkin code without tests, but I think you all know what I mean.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Writing tests for an unknown code is either difficult or tiresome; difficult, if I decide to understand large chucks of the project before writing a lick of code; tiresome, if I chose to only understand the module that I am changing and just mock the rest of classes when unit testing. &amp;nbsp;In reality, It should be a bit of both.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the past I made lots and lots of mock objects by making classes that implement a certain interface or try to instantiate a class with lots of dependency, when really, I only care about one or two methods in the class. It's a tiresome, verbose, and just plain an ugly thing to do for writing a unit test.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Fortunately, I came across &lt;a href="http://code.google.com/p/mockito/"&gt;Mockito&lt;/a&gt; with allows you to mock and stub classes effortlessly.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Take the &lt;code&gt;StatsManager&lt;/code&gt; class that has a &lt;code&gt;genderCount()&lt;/code&gt; method.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;public class StatsManager {&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; private JDBCTemplate template;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; public long genderCount(Gender gender) {&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; //perform some business logic&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;...&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; }&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; public void setJDBCTemplate(JDBCTemplate template) {&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; this.template = template;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; }&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;...&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;}&lt;/code&gt;&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Say I want to make a change to the &lt;code&gt;genderCount()&lt;/code&gt; method and I need an unit test to validate my change.&lt;br /&gt;&lt;br /&gt;Before Mockito, I would need to instantiate an instance of &lt;code&gt;JDBCTemplate&lt;/code&gt;. &amp;nbsp;It happens that &lt;code&gt;JDBCTemplate&lt;/code&gt; needs an &lt;code&gt;javax.sql.DataSource&lt;/code&gt; instance to work. I would then try to make a mock class of this interface, but then it turns out that &lt;code&gt;javax.sql.DataSource&lt;/code&gt; has a dependency &lt;code&gt;javax.sql.Connection&lt;/code&gt; so I have to mock that class and world goes round and round... but I never finishing mocking!&lt;br /&gt;&lt;br /&gt;What is it that I really need in order to test this code? It's the logic in &lt;code&gt;genderCount()&lt;/code&gt; that I want to test, and don't want to concern myself with all these other setup classes/interfaces. Infact, I know that &lt;code&gt;queryAsList(String sql)&lt;/code&gt; is the only method called on the &lt;code&gt;JDBCTemplate&lt;/code&gt; class in &lt;code&gt;StatsManager.genderCount()&lt;/code&gt; .&amp;nbsp;All I want is a certain List of results when &lt;code&gt;genderCount()&lt;/code&gt; is called.&lt;br /&gt;&lt;br /&gt;This is exactly what Mockito give me! Here is an example&lt;br /&gt;&lt;br /&gt;&lt;code&gt;public class StatsManagerTest {&lt;br /&gt;&lt;br /&gt;@Test&lt;br /&gt;public void testGenderCount() {&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; StatsManager manager = new StatsManager();&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; JDBCTemplate template = mock(JDBCTemplate.class)&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; List results = new ArrayList();&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; //initialize list.&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; ...&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; when(template.queryAsList(anyString())).thenReturns(results);&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;div style="font-family: Times;"&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/div&gt;&lt;code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; long maleCount = template.genderCount(Gender.MALE);&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; //Assert a bunch of stuff&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; ...&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; long femaleCount = template.genderCount(Gender.FEMALE);&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; //Assert a bunch of stuff&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; ...&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&lt;br /&gt;}&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&lt;br /&gt;}&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;The key thing to notice here is the &amp;nbsp;&lt;code&gt;when()&lt;/code&gt;&amp;nbsp;and&amp;nbsp;&lt;code&gt;thenReturns()&lt;/code&gt; pair. What this is doing is that when &lt;code&gt;queryAsList()&lt;/code&gt; is called regardless of what string is passed as a parameter, return this fixed list of results.&lt;br /&gt;That's it! My unit test is concise/readable, free from a bunch of setup code. &amp;nbsp; I can always setup a different list of results to test against in my unit test.&lt;br /&gt;&lt;br /&gt;It makes writing unit tests fun versus a necessary evil.&lt;br /&gt;&lt;code&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;/code&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-9076686722919737804?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/9076686722919737804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=9076686722919737804' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/9076686722919737804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/9076686722919737804'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2012/01/mockito-is-just-awesomeness.html' title='Mockito is just awesomeness'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-2673812340644675902</id><published>2012-01-28T21:02:00.000-08:00</published><updated>2012-01-28T21:06:21.602-08:00</updated><title type='text'>Back from Java haitus</title><content type='html'>It's been a whole 10 months since I've written any sensible Java code. Been developing a LAMP stack (we'll not exactly; &lt;a href="http://www.lighttpd.net/"&gt;lighttpd&lt;/a&gt; instead of &lt;a href="http://httpd.apache.org/"&gt;apache&lt;/a&gt;). Lots of PHP, Javascript/JQuery, HTML, CSS. &amp;nbsp;Let's just say I've been itching for the type-safety.&lt;br /&gt;&lt;br /&gt;This coming up in the next couple of months: &lt;a href="http://hadoop.apache.org/"&gt;Hadoop&lt;/a&gt;, &lt;a href="http://hive.apache.org/"&gt;Hive&lt;/a&gt;, &lt;a href="http://www.cascading.org/"&gt;Cascading&lt;/a&gt;, &lt;a href="http://www.springsource.org/"&gt;Spring&lt;/a&gt;, &lt;a href="http://www.couchbase.com/membase"&gt;Membase&lt;/a&gt; and maybe even some &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; and &lt;a href="http://akka.io/"&gt;Akka&lt;/a&gt;! &amp;nbsp;Stay tuned...&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-2673812340644675902?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/2673812340644675902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=2673812340644675902' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/2673812340644675902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/2673812340644675902'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2012/01/back-from-java-haitus.html' title='Back from Java haitus'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-2524730221114030569</id><published>2010-11-09T13:18:00.000-08:00</published><updated>2010-11-09T13:19:17.912-08:00</updated><title type='text'>BigMemory is out! Garbage Collection RIP</title><content type='html'>I'm sure like many of you, I tend to browse DZone for interesting articles/blog posts. As a guy who works on Java server-side software, articles related Garbage Collection always catches my eye.  Today while browsing on DZone I came across this article on &lt;a href="http://www.dzone.com/links/r/hiranya_jayathilaka_taming_the_java_garbage_colle.html"&gt;Garbage Collection tuning&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Halfway through reading the article I realized the irony: I'm reading a pretty well written article on how to tune your Java Garbage Collector on the same day &lt;a href="http://terracotta.org/"&gt;Terracotta&lt;/a&gt; announced GA for our&amp;nbsp;&lt;a href="http://terracotta.org/bigmemory?src=/index.html"&gt;BigMemory&lt;/a&gt; product.  As I spelled out &lt;a href="http://javasmith.blogspot.com/2010/10/terracotta-big-memory-tale-of-eating.html"&gt;here&lt;/a&gt; and &lt;a href="http://javasmith.blogspot.com/2010/10/ehcache-bigmemory-simple-high.html"&gt;here&lt;/a&gt; BigMemory makes the need for tuning unnecessarily. And if your talking about Java Heaps large; GC Tuning? Forgetaboutit!&lt;br /&gt;&lt;br /&gt;I know as a developer I would rather work on making my product &lt;a href="http://sarosblog.blogspot.com/2010/11/implementing-fast-concurrent-object.html"&gt;better, faster and more concurrent&lt;/a&gt; then dread that GC gremlin showing up pausing my application and killing the buzz. If you do want to make YOUR application better and not let GC get in the way to that, check out the BigMemory product &lt;a href="http://terracotta.org/bigmemory?src=/index.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Articles on Garbage Collection just got a whole lot less interesting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-2524730221114030569?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/2524730221114030569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=2524730221114030569' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/2524730221114030569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/2524730221114030569'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2010/11/bigmemory-is-out-garbage-collection-rip.html' title='BigMemory is out! Garbage Collection RIP'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-2796979713815382759</id><published>2010-10-26T22:00:00.000-07:00</published><updated>2010-10-27T10:50:26.661-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caching'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='high availability'/><category scheme='http://www.blogger.com/atom/ns#' term='bigmemory'/><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><category scheme='http://www.blogger.com/atom/ns#' term='Terracotta'/><category scheme='http://www.blogger.com/atom/ns#' term='ehcache'/><title type='text'>Ehcache BigMemory: Simple High Availability, Even Simpler</title><content type='html'>My collegue Jason @ Terracotta did a nice post on using &lt;a href="http://jvoegele.blogspot.com/2010/10/terabyte-scale-for-jruby-and-rails.html"&gt;Ehcache with JRuby&lt;/a&gt;; which led to a discussion on a long list of features we implemented for Enterprise Ehcache (check out the discussion thread on Jason's Blog).&lt;br /&gt;&lt;br /&gt;Adding to Jason's feature list, I would like to discuss HA (High Availability) in Ehcache and explain why our BigMemory product makes tuning HA even simpler. Lets review how we do HA in Enterprise Ehcache. In Enterprise Ehcache, clients going down is no big deal since the data is present on the servers as well. Our HA focuses on protecting our servers. &amp;nbsp;In Enterprise Ehcache you can define one or many server groups. Each group consists of a cluster of servers. The cluster has to decide which node is going to be the active server. This is decided by having an election where a node is selected to be the active server. The rest of the nodes in the cluster are waiting in passive standby ready to take over if the active node fails.&lt;br /&gt;&lt;br /&gt;In order to actually detect when a failover needs to happen, we wrote a configurable HC (Health checker). &amp;nbsp;Our HC detects errors that won't show up as a normal network disconnect or failure, such as a network cable being pulled. Because Enterprise Ehcache is written in Java, we also had to deal with long GCs. So we designed our HC to detect long GCs as well.&lt;br /&gt;&lt;br /&gt;Based on your use case, you may want to change the HC settings depending on what your tolerance is for network disruption and long GCs. Before you go about changing your settings, you might want to check out these files:&lt;br /&gt;&lt;br /&gt;&lt;code&gt; $TERRACOTTA_KIT/platform/config-samples/tc-config-healthchecker-aggressive.xml&lt;br /&gt;$TERRACOTTA_KIT/platform/config-samples/tc-config-healthchecker-aggressive.xmltc-config-healthchecker-development.xml&lt;br /&gt;$TERRACOTTA_KIT/platform/config-samples/tc-config-healthchecker-aggressive.xmltc-config-healthchecker-production.xml&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Depending on what you're doing and what your requirements are, picking one of the settings above should be suffice.&lt;br /&gt;&lt;br /&gt;Now let's discuss these properties:&lt;br /&gt;&lt;br /&gt;&lt;code&gt; l2.healthcheck.l2.ping.idletime=3000&lt;br /&gt;l2.healthcheck.l2.ping.interval=1000&lt;br /&gt;l2.healthcheck.l2.ping.probes=2&lt;br /&gt;l2.healthcheck.l2.socketConnectTimeout=5&lt;br /&gt;l2.healthcheck.l2.socketConnectCount=2&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Above are the properties you have to work with for HC. &amp;nbsp;The HC starts off using the ping.idletime. This is the maximum amount of time that can elapse between the last time data was received from the corresponding node. In this case the idletime is 3000 milliseconds, after which the HC notes "Hey, didn't receive any data from the corresponding node, I should check on that node."&lt;br /&gt;&lt;br /&gt;To check on the health of the node, it tries to ping the node in intervals, in which the interval length is defined by ping.interval. You can push this number down to get more granularity. If the corresponding node doesn't respond within the ping.interval then it either tries to probe again because the ping.probes countdown hasn't completed, or it checks socketConnectCount and see if its allowed to make any more socket connections. If not, it declares the corresponding node DEAD.&lt;br /&gt;&lt;br /&gt;In the example above, since the socketConnectCount is set to 2, it will try to make another socket connection. If it cannot make the socket connection within (socketConnectTimeout * pingInterval) ms, then it will declare the node DEAD.  In our example, the interval length 5000 ms. Once it established a connection it will repeat&amp;nbsp;the ping probe cycle again.&lt;br /&gt;&lt;br /&gt;The maximum time it will take the HC to detect a network disruption is ( ping.idletime + (ping.probes * ping.interval) + (socketConnectTimeout * ping.interval) ) ms.  If the problem is longGC, then the connection will happen, but the pings won't receive a response. The maximum time HC takes to detect a long GC is ( socketConnectCount * ( ping.idletime + (ping.probes * ping.interval) + (socketConnectTimeout * ping.interval) ) ) ms. &lt;br /&gt;&lt;br /&gt;If you have a short tolerance for network disruption, but your ok with having lengthy long GCs, then you can decrease the ping.idletime and increase the socketConnectCount; you tune based on your tolerances. &lt;a href="http://www.terracotta.org/documentation/ga/high-availability.html"&gt;Here's some detailed documentation on the HA settings.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;With &lt;a href="http://javasmith.blogspot.com/2010/10/terracotta-big-memory-tale-of-eating.html"&gt;BigMemory in our server&lt;/a&gt; FORGET ALL THAT IS WRITTEN ABOVE.&lt;br /&gt;&lt;br /&gt;Our HC has all these different properties because we had to be tolerant of Long GCs. When a node is in long GC, it will make a socket connection but not be able to complete the ping probe cycle. but now with BigMemory you probably don't ever need to change these settings, unless you have people tripping over your network cables.&lt;br /&gt;&lt;br /&gt;Unlike Long GCs, network disruptions is something you probably know about and its easier to guess what that tolerance should be. Not having to tune for long GCs makes HC configuration simple. You only need to tune for YOUR own environment (i.e. crappy network, or clumsy workers) and not for something that is specific to Java (Long GCs).&lt;br /&gt;&lt;br /&gt;Imagine what it can do for you. &lt;a href="http://terracotta.org/bigmemory?src=/index.html"&gt;Check out our beta here.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-2796979713815382759?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/2796979713815382759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=2796979713815382759' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/2796979713815382759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/2796979713815382759'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2010/10/ehcache-bigmemory-simple-high.html' title='Ehcache BigMemory: Simple High Availability, Even Simpler'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-2513407091437028077</id><published>2010-10-17T10:44:00.000-07:00</published><updated>2010-10-18T17:09:23.943-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='bigmemory'/><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><category scheme='http://www.blogger.com/atom/ns#' term='Terracotta'/><category scheme='http://www.blogger.com/atom/ns#' term='ehcache'/><category scheme='http://www.blogger.com/atom/ns#' term='gc'/><title type='text'>BigMemory: Followup Q and A</title><content type='html'>I got quite a few responses to my &lt;a href="http://javasmith.blogspot.com/2010/10/terracotta-big-memory-tale-of-eating.html"&gt;post on BigMemory in the Terracotta Server&lt;/a&gt;. It seems like people are quite confused on what it actually is.&lt;br /&gt;&lt;br /&gt;Here's some answers to a few questions I received:&lt;br /&gt;&lt;br /&gt;1. &lt;i&gt;Why can't they (Terracotta) put garbage collector on another cpu core and gain performance?&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;I think there is a misunderstanding about the cost of Garbage Collection. The Full GC pause (which is when&amp;nbsp;all application threads are paused) is what the GC problem in Java is all about. It is tolerable when your Heap is 1-2 GB. But anything beyond that you get 4,5,8 seconds GC pauses. Besides, if you don't run ParallelGC then it will use one core anyway. But you DO want to have your garbage collector using all the cores so it will complete faster and have less pauses.&lt;br /&gt;&lt;br /&gt;2. (&lt;i&gt;In References to the question above) Then put it on another thread and how about pausing one thread at a time ?&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Again this is not possible AFAIK to do with the Sun/Oracle JVM. Also, Full GC Pauses are a necessary evil for the GC algorithm they are using. Even if this was possible, it would not solve the problem of unpredictability.&lt;br /&gt;&lt;br /&gt;3. &lt;i&gt;I can't believe there are no GC pauses ... or you guys might have made memory management solution like an OS in java.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;The idea of have direct memory allocation in Java is no big secret. There is an -XX:MaxDirectMemorySize flag to tell the JVM how much direct memory to allocate. &amp;nbsp;The value add of Terracotta is to use this direct memory space in a way that is fast and does got fragment. &lt;br /&gt;&lt;br /&gt;4. &lt;i&gt;Using direct memory allocated by the JVM is useless because it is so much slower then the Heap.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Access to direct memory is NOT slower than Heap. There are two things that contribute to the perceived slowness of direct memory. Serializing and deserializing data to and from direct memory; and allocating and cleaning up direct memory buffers. At Terracotta we solved the direct memory and cleanup problem. On the Terracotta Server we don't pay for the serialization/deserialization cost. On Enterprise Ehcache (unclustered) we do pay a serialization/deserialization cost, but compare this CPU cost to having to deal with Full GC Pauses on the Heap. The tradeoff is well worth it.&amp;nbsp;Besides BigMemory using the Heap as part tier storage strategy; Heap to OffHeap to Disk. It's an age old principle in computer science (think Virtual Memory). We avoid the serialization/deserialization cost for frequently used objects by having those in Heap, then having a big part of your cache on OffHeap to avoid long FullGC and the rest spilling over to disk.&lt;br /&gt;&lt;br /&gt;For the additional CPU cost what you get in return is predictable latency and speed with all the memory your Java process desires.&amp;nbsp;Find an app where you do see Full GC pauses and checkout the &lt;a href="http://terracotta.org/bigmemory?src=/index.html"&gt;beta&lt;/a&gt; to see for yourself.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-2513407091437028077?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/2513407091437028077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=2513407091437028077' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/2513407091437028077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/2513407091437028077'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2010/10/bigmemory-followup-q-and.html' title='BigMemory: Followup Q and A'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-2789415231177871197</id><published>2010-10-14T00:22:00.000-07:00</published><updated>2010-10-14T13:32:51.032-07:00</updated><title type='text'>OmmWriter Plug</title><content type='html'>Just wanted to plug this fantastic software for the Mac. &lt;a href="http://www.ommwriter.com/"&gt;OmmWriter&lt;/a&gt;.  Writing is a painful excercise for me since I get distracted pretty easily. With so many application like IDEs, chat, mail, brower, twitter etc. open its really hard to concentrate.  When I try to write about any topic, I always have a tendency to fact check every sentence, which takes me on reading tangents. OmmWriter runs in full-screen mode and removes any sort of notification. I can write with purpose and bang out a blog post really quickly. Give these guys a try, their version 1 is free and the newest one is a paid version.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-2789415231177871197?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/2789415231177871197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=2789415231177871197' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/2789415231177871197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/2789415231177871197'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2010/10/ommwriter-plug.html' title='OmmWriter Plug'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-2738096896704943924</id><published>2010-10-13T23:51:00.001-07:00</published><updated>2010-10-14T13:51:37.392-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caching'/><category scheme='http://www.blogger.com/atom/ns#' term='big memory'/><category scheme='http://www.blogger.com/atom/ns#' term='elastic caching'/><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><category scheme='http://www.blogger.com/atom/ns#' term='Terracotta'/><category scheme='http://www.blogger.com/atom/ns#' term='NoGC'/><category scheme='http://www.blogger.com/atom/ns#' term='ehcache'/><category scheme='http://www.blogger.com/atom/ns#' term='heap'/><title type='text'>Terracotta BigMemory: A tale of eating our own code</title><content type='html'>&lt;div&gt;Terracotta (The company I work for) recently came out with a beta release for their &lt;a href="http://www.terracotta.org/bigmemory?src=/index.html"&gt;BigMemory&lt;/a&gt; product. Our claim is that if you use Ehcache BigMemory then those GC problems go away. If you don't know what Ehcache or Terracotta is you can find out &lt;a href="http://www.terracotta.org/ehcache/distributed-cache/ehcache-fx"&gt;here.&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is far from just a claim, we didn't simply didn't write BigMemory, ran a few tests, and release the Beta. We took BigMemory and freed our own Terracotta Server for GC constraints that most Java server product have.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what exactly did we do? In Terracotta we keep a representation of distributed objects in your server. For our clustered Ehcache product we keep a representation of cache segments and cache entries on the server. As the cache grows, we need to keep track of the keys associated with the cache segment, as well as have more cache entries representations on the server. The Terracotta Server has the ability to flush cache entries to disk when we detect memory pressure on our server. and fault in objects when cache entries are needed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To accommodate the keys on the server, you had two options. One is the increase heap so that more keys could fit on the server. The second is to add additional Terracotta Servers to the cluster so that the segments (and their keys) are distributed to among many servers. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Adding more heap threw us into the classic GC problem. Once you start getting into heap sizes of 5-6GB, you start seeing 5-8 second GC pauses. Adding stripes solves the problem and worked for our customers as well.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But we found a pattern emerging. Customers were purchasing huge boxes (I'm going regret saying huge a few months from now ), 32 GB ram and 16 cores of processing power. They were like "We want to run your servers on this thing." And they did what everyone does for Java Servers, they basically run multiple JVMs (if possible) on the same box and deal with the added complexity and unpredicatability and probably says a prayer or two. I'm sure you all understand what I mean by complexity, but what do I mean by unpredictability. Lets say you run your servers with small heaps and your getting a 2 second GC, but will so many JVMs, how do you know your GCs will not be staggered. Meaning if you had 16 processes running and they GCed one after the other. That is a 32 second pause. Get the picture?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We figured, there must be a better way. So we built BigMemory and put it in our server. Now you can take our pure Java Terracotta Server, have it use that 32 GB ram and still get less than 1 second pauses. Practically No GC.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For anyone who spent countless hours like I have tuning GC is going to love this. We ran and messed around with every knob the Sun (now Oracle) gave use to tune GC. When we put in BigMemory, we just deleted all those settings. Our heap is small enough so that default Java settings are good enough!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;End result? Our Terracotta Server with BigMemory enabled can achieve higher density will less servers and best of all you can get predictable latency out of them.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Check out &lt;a href="http://www.terracotta.org/bigmemory?src=/index.html"&gt;BigMemory&lt;/a&gt; and let me know if it works just as well for you.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-2738096896704943924?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/2738096896704943924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=2738096896704943924' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/2738096896704943924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/2738096896704943924'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2010/10/terracotta-big-memory-tale-of-eating.html' title='Terracotta BigMemory: A tale of eating our own code'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-1921505022610811920</id><published>2010-02-17T07:53:00.000-08:00</published><updated>2010-02-17T09:53:43.813-08:00</updated><title type='text'>automagically cluster Lift web sessions with Terracotta</title><content type='html'>&lt;a href="http://liftweb.net/"&gt;Lift Web Framework&lt;/a&gt; Is a MVC Framework written in &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;, Which are two things I know exactly nothing about.  Being that, I thought It would be a good example to show how easy it is to cluster web session using terracotta new express web session product. Here's a link to our &lt;a href="http://www.terracotta.org/documentation/betadocs/beta-documentation-9.html"&gt;Beta&lt;/a&gt; ...&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Part 1: The Lift/Scala Thing...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So first I had to figure out what the deal with Lift is about. Good thing there's a fairly simple tutorial to create a basic HelloWorld lift webapp &lt;a href="http://liftweb.net/docs/getting_started/mod_master.html#x1-50001.3"&gt;here&lt;/a&gt;. First let's download and install all the bits you need to write a Lift web app, fortunately for me it was just the Scala Eclipse Plugin.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let us create a maven project:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;mvn archetype:generate -U \&lt;br /&gt;-DarchetypeGroupId=net.liftweb \&lt;br /&gt;-DarchetypeArtifactId=lift-archetype-blank \&lt;br /&gt;-DarchetypeVersion=1.0 \&lt;br /&gt;-DremoteRepositories=http://scala-tools.org/repo-releases \&lt;br /&gt;-DgroupId=com.examples.terracotta \&lt;br /&gt;-DartifactId=clusteredCounter \&lt;br /&gt;-Dversion=1.0-SNAPSHOT&lt;br /&gt;&lt;br /&gt;cd clusteredCounter&lt;br /&gt;mvn jetty:run&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Now you got yourself a fully functioning hello world webapp. Let's add some code where we are actually saving and displaying session data.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;add a Lift Snippet that would process url parameters add then to the session and then display all the session attributes:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;package com.examples.terracotta.snippet&lt;br /&gt;&lt;br /&gt;import javax.servlet.http._&lt;br /&gt;import net.liftweb.http._&lt;br /&gt;import net.liftweb.util._&lt;br /&gt;import net.liftweb.util.Helpers._&lt;br /&gt;&lt;br /&gt;import net.liftweb.http.SessionVar&lt;br /&gt;import scala.collection.mutable.HashMap&lt;br /&gt;import scala.xml._&lt;br /&gt;import java.util.Enumeration&lt;br /&gt;import scala.collection.mutable.HashSet&lt;br /&gt;&lt;br /&gt;class ViewSubmission {&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def showStuff : NodeSeq = {&lt;br /&gt;&lt;br /&gt;var title = S.param("title").openOr("")&lt;br /&gt;var url = S.param("url").openOr("")&lt;br /&gt;&lt;br /&gt;S.servletSession.get.setAttribute(title, url)&lt;br /&gt;&lt;br /&gt;var e = S.servletSession.get.getAttributeNames&lt;br /&gt;val names = new HashSet[String]&lt;br /&gt;while (e.hasMoreElements()) {&lt;br /&gt; val name = e.nextElement().asInstanceOf[String]&lt;br /&gt; names += name&lt;br /&gt; println(names)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&amp;lt;table&amp;gt; {&lt;br /&gt;   for (name &amp;lt;- names) yield&lt;br /&gt;     &amp;lt;tr&amp;gt;&lt;br /&gt;      &amp;lt;td&amp;gt;Title&amp;lt;/td&amp;gt;&lt;br /&gt;      &amp;lt;td&amp;gt;{name}&amp;lt;/td&amp;gt;&lt;br /&gt;     &amp;lt;/tr&amp;gt;&lt;br /&gt;     &amp;lt;tr&amp;gt;&lt;br /&gt;      &amp;lt;td&amp;gt;Url&amp;lt;/td&amp;gt;&lt;br /&gt;      &amp;lt;td&amp;gt;{S.servletSession.get.getAttribute(name)}&amp;lt;/td&amp;gt;&lt;br /&gt;     &amp;lt;/tr&amp;gt;&lt;br /&gt;}&amp;lt;/table&amp;gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Edit the index.html to show edit and show session data:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;lift:surround with="default" at="content"&amp;gt;&lt;br /&gt;&amp;lt;table&amp;gt;&lt;br /&gt; &amp;lt;lift:snippet type="viewSubmission:showStuff" /&amp;gt;&lt;br /&gt;&amp;lt;/table&amp;gt;&lt;br /&gt;&amp;lt;form&amp;gt;&lt;br /&gt; &amp;lt;tr&amp;gt;&lt;br /&gt;  &amp;lt;td&amp;gt;Title&amp;lt;/td&amp;gt;&lt;br /&gt;  &amp;lt;td&amp;gt;&lt;br /&gt;   &amp;lt;input type="text" name="title" /&amp;gt;&lt;br /&gt;  &amp;lt;/td&amp;gt;&lt;br /&gt; &amp;lt;/tr&amp;gt;&lt;br /&gt; &amp;lt;tr&amp;gt;&lt;br /&gt;  &amp;lt;td&amp;gt;Url&amp;lt;/td&amp;gt;&lt;br /&gt;  &amp;lt;td&amp;gt;&lt;br /&gt;   &amp;lt;input type="text"  name="url"/&amp;gt;&lt;br /&gt;  &amp;lt;/td&amp;gt;&lt;br /&gt; &amp;lt;/tr&amp;gt;&lt;br /&gt; &amp;lt;tr&amp;gt;&lt;br /&gt;  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;  &amp;lt;td&amp;gt;&amp;lt;input type="submit" value="Add" /&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt; &amp;lt;/tr&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;/lift:surround&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Run mvn -Djetty.port=9999 jetty:run and another instance with&lt;/div&gt;&lt;div&gt;mvn -Djetty.port=9999 jetty:run. got to http://localhost:8888 and http://localhost:9999. you can only see the data you added to each local web session.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now the fun part...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Part 2: Clustering the web session&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First we need to add our express web session jar to the pom.xml as a dependency:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt;&amp;lt;groupid&amp;gt;org.terracotta.session&amp;lt;/groupid&amp;gt;&lt;br /&gt;&amp;lt;artifactid&amp;gt;terracotta-session&amp;lt;/artifactid&amp;gt;&lt;br /&gt;&amp;lt;version&amp;gt;1.1.0-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;br /&gt;and also Terracotta Maven Repo information..&lt;br /&gt;&lt;br /&gt;&amp;lt;repository&amp;gt;&lt;br /&gt;&amp;lt;id&amp;gt;terracotta-snapshots&amp;lt;/id&amp;gt;&lt;br /&gt;&amp;lt;url&amp;gt;http://www.terracotta.org/download/reflector/maven2&amp;lt;/url&amp;gt;&lt;br /&gt;&amp;lt;releases&amp;gt;&lt;br /&gt;  &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;&lt;br /&gt;&amp;lt;/releases&amp;gt;&lt;br /&gt;&amp;lt;snapshots&amp;gt;&lt;br /&gt;  &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;&lt;br /&gt;&amp;lt;/snapshots&amp;gt;&lt;br /&gt;&amp;lt;/repository&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let us add our terracotta filter for clustering:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;filter&amp;gt;&lt;br /&gt; &amp;lt;filter-name&amp;gt;terracotta&amp;lt;/filter-name&amp;gt;&lt;br /&gt; &amp;lt;display-name&amp;gt;Terracotta Session Filter&amp;lt;/display-name&amp;gt;&lt;br /&gt; &amp;lt;!-- The filter class is specific to the application server. --&amp;gt;&lt;br /&gt; &amp;lt;filter-class&amp;gt;org.terracotta.session.TerracottaJetty61xSessionFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt; &amp;lt;init-param&amp;gt;&lt;br /&gt;  &amp;lt;param-name&amp;gt;tcConfigUrl&amp;lt;/param-name&amp;gt;&lt;br /&gt;  &amp;lt;!--&lt;br /&gt;   &amp;lt;param-value&amp;gt; of type tcConfigUrl has a &amp;lt;param-value&amp;gt; containing the&lt;br /&gt;   URL or filepath (for example, /lib/tc-config.xml) to tc-config.xml.&lt;br /&gt;  --&amp;gt;&lt;br /&gt;  &amp;lt;param-value&amp;gt;localhost:9510&amp;lt;/param-value&amp;gt;&lt;br /&gt; &amp;lt;/init-param&amp;gt;&lt;br /&gt;&amp;lt;/filter&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;filter-mapping&amp;gt;&lt;br /&gt; &amp;lt;filter-name&amp;gt;terracotta&amp;lt;/filter-name&amp;gt;&lt;br /&gt; &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;&amp;lt;/filter-mapping&amp;gt;&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Now start our terracotta server, &lt;a href="http://www.terracotta.org/dl/oss-download-catalog"&gt;download here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Start are terracotta server and then run the jetty servers again. this time you can see session data on entered in on one server appear on the other.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.box.net/shared/h9n9c023he"&gt;Example Project&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-1921505022610811920?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/1921505022610811920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=1921505022610811920' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/1921505022610811920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/1921505022610811920'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2010/02/automagically-cluster-web-sessions-in.html' title='automagically cluster Lift web sessions with Terracotta'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-54222399902706373</id><published>2009-06-28T00:34:00.000-07:00</published><updated>2009-06-29T12:14:53.756-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Terracotta'/><category scheme='http://www.blogger.com/atom/ns#' term='Performance Tuning'/><title type='text'>Performance Tuning Hibernate Second-level Cache</title><content type='html'>Lately I've been spending ALOT of time performance testing and tuning of a hibernate app using a Terracotta implementation of Hibernate Second-level Cache. I thought it would be interesting to do a series of posts that walk through different use-cases and how we performance tuned them. While doing so, I thought it would also interesting to demonstrate various tools that can help with the tuning.&lt;br /&gt;&lt;br /&gt;Before we continue, I think it is worth while to read my colleagues posts on performance testing &lt;a href="http://javathink.blogspot.com/2009/06/how-to-performance-test.html"&gt;here&lt;/a&gt;, &lt;a href="http://dsoguy.blogspot.com/2007/06/why-your-distributed-tests-are-lying-to.html"&gt;here&lt;/a&gt;, and &lt;a href="http://dsoguy.blogspot.com/2007/07/what-were-those-results-again.html"&gt;here&lt;/a&gt;.  Their advice seems simple enough. But trust me, it's really easy to fall off the wagon when it comes to this stuff.  The work itself is very tedious, so it's easy to convince yourself that "Yeah, this patch is it, this is the final run", or "I know the bottleneck is the CPU for sure! Why bother looking at the memory and/or disk characteristics."  Assumptions and unfounded optimism can easily get you rat-holed to a dead end.  Bottom line: don't assume anything and collect everything.&lt;br /&gt;&lt;br /&gt;The project that we are going to look at is a simple hibernate app. The app itself just warms up the 2nd-level cache and then accesses the cache, and depending on the use case writes, in a non-partitioned fashion in the following modes: read-only, read-mostly and read-write.&lt;br /&gt;&lt;br /&gt;the various tools I used to tune is:&lt;br /&gt;- &lt;a href="http://www.ibm.com/developerworks/aix/library/au-analyze_aix/"&gt;nmon&lt;/a&gt; a basic tool to look at cpu, memory, disk and network metrics.&lt;br /&gt;- jmap,jhat,jstat to analyze heap and garbage collector metrics, these tools are included in the jdk.&lt;br /&gt;- VisualVM, very cool tool to look at JMX Beans, nmon type characteristics as well as a light-weight thread monitoring tool.&lt;br /&gt;- Terracotta Dev Console, great tool for looking at terracotta specific characteristics as well as general info (cpu, memory etc.)&lt;br /&gt;- Good old fashion thread dumps (kill -3 java_pid)&lt;br /&gt;&lt;br /&gt;Ok, so that's our test and tools. More of the nitty-gritty to come :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-54222399902706373?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/54222399902706373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=54222399902706373' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/54222399902706373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/54222399902706373'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2009/06/lately-ive-been-spending-alot-of-time.html' title='Performance Tuning Hibernate Second-level Cache'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-7662806000002252726</id><published>2009-06-23T23:28:00.001-07:00</published><updated>2009-06-23T23:48:11.820-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><title type='text'>Carrying over Eclipse Plugins from Ganymede to Galileo</title><content type='html'>Looks like a new version of Eclipse is coming &lt;a href="http://eclipse.org/"&gt;out&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;Over the course of using Ganymede I accumulated various plugins that I want to carry over to Galileo. I figure there must be a way to export and then import those plugin Urls.&lt;br /&gt;&lt;br /&gt;So first I launched my Ganymede and go to Help-&gt; Software Updates..&lt;br /&gt;Then click "Manage Sites.." You should see the following Dialog:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_BfP5n5CCiFI/SkHKMW_wteI/AAAAAAAAA8E/q_GhNmceNTA/s1600-h/eclipse_availabe_software.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 224px;" src="http://1.bp.blogspot.com/_BfP5n5CCiFI/SkHKMW_wteI/AAAAAAAAA8E/q_GhNmceNTA/s320/eclipse_availabe_software.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5350780145973114338" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Click the checkboxes for which site Urls you want to export and Click "Export" and same the file. I saved the suggested bookmarks.xml to my Desktop.&lt;br /&gt;&lt;br /&gt;Now I downloaded the Galileo RC4 (Galileo final release comes out tommorrow) and launched it.&lt;br /&gt;Now go to Help-&gt;Install New Software..&lt;br /&gt;&lt;br /&gt;Click on the link "Available Sofware Sites" like the one in the screenshot below:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_BfP5n5CCiFI/SkHJA7iGQDI/AAAAAAAAA78/L1sX447AcM4/s1600-h/eclipse_part1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 215px;" src="http://1.bp.blogspot.com/_BfP5n5CCiFI/SkHJA7iGQDI/AAAAAAAAA78/L1sX447AcM4/s320/eclipse_part1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5350778850110750770" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Then select Import and select the file you saved from Ganymede.  Now make sure you have "Hide items that are already installed" Otherwise it will take a long time to come up with the plugin list. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_BfP5n5CCiFI/SkHLYw-Sp2I/AAAAAAAAA8M/lVdcER2rRCM/s1600-h/eclipse_select_install.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 210px;" src="http://1.bp.blogspot.com/_BfP5n5CCiFI/SkHLYw-Sp2I/AAAAAAAAA8M/lVdcER2rRCM/s320/eclipse_select_install.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5350781458616330082" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now just install the plugins you want to install. Can't make any promises that it will actually work with Galileo :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-7662806000002252726?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/7662806000002252726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=7662806000002252726' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/7662806000002252726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/7662806000002252726'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2009/06/carrying-over-eclipse-plugins-from.html' title='Carrying over Eclipse Plugins from Ganymede to Galileo'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_BfP5n5CCiFI/SkHKMW_wteI/AAAAAAAAA8E/q_GhNmceNTA/s72-c/eclipse_availabe_software.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-3440158540216741934</id><published>2009-06-21T19:26:00.000-07:00</published><updated>2009-06-21T20:03:56.655-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Terracotta'/><category scheme='http://www.blogger.com/atom/ns#' term='Clustered Events'/><title type='text'>Terracotta Cluster Events: A simple example</title><content type='html'>My friend instant messaging me this weekend about this app he is writing using Terracotta.  He is concerned about when a node leaves/joins and terracotta cluster and was doing some really weird stuff with the JVM Shutdown hook.  I decided to do a quick blog post about Terracotta Clustered Events which is a simple way for an app to listen for terracotta cluster wide events.&lt;br /&gt;&lt;br /&gt;So first i'll generate a new project using the pojo-archetype:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-5:generate \&lt;br /&gt;-DarchetypeGroupId=org.terracotta.maven.archetypes \&lt;br /&gt;-DarchetypeArtifactId=pojo-archetype \&lt;br /&gt;-DarchetypeVersion=1.5.0-SNAPSHOT \&lt;br /&gt;-DgroupId=org.terracotta.examples \&lt;br /&gt;-DartifactId=clusteredapi-examples \&lt;br /&gt;-Dversion=1.0.0 \&lt;br /&gt;-DremoteRepositories=http://www.terracotta.org/download/reflector/maven2&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The the following prompt appears:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[INFO] Scanning for projects...&lt;br /&gt;[INFO] ------------------------------------------------------------------------&lt;br /&gt;[INFO] Building Maven Default Project&lt;br /&gt;[INFO]    task-segment: [org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-5-parent-patch-SNAPSHOT:generate] (aggregator-style)&lt;br /&gt;[INFO] ------------------------------------------------------------------------&lt;br /&gt;[INFO] Preparing archetype:generate&lt;br /&gt;[INFO] No goals needed for project - skipping&lt;br /&gt;[INFO] Setting property: classpath.resource.loader.class =&gt; 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.&lt;br /&gt;[INFO] Setting property: velocimacro.messages.on =&gt; 'false'.&lt;br /&gt;[INFO] Setting property: resource.loader =&gt; 'classpath'.&lt;br /&gt;[INFO] Setting property: resource.manager.logwhenfound =&gt; 'false'.&lt;br /&gt;[INFO] [archetype:generate]&lt;br /&gt;[INFO] Generating project in Interactive mode&lt;br /&gt;[INFO] Archetype repository missing. Using the one from [org.terracotta.maven.archetypes:pojo-archetype:1.5.0-SNAPSHOT] found in catalog local&lt;br /&gt;[INFO] Using property: groupId = org.terracotta.examples&lt;br /&gt;[INFO] Using property: artifactId = clusterapi-example&lt;br /&gt;[INFO] Using property: version = 1.0.0&lt;br /&gt;[INFO] Using property: package = org.terracotta.examples&lt;br /&gt;Define value for property 'description': :&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now enter in a description, I typed in "This is an example project to demonstrate java clustered api" and then was prompted again and Typed in "Y"&lt;br /&gt;Now we have a project to test out terracotta clustered api.&lt;br /&gt;&lt;br /&gt;The clustered event api interfaces are available from the terracotta api jar, let's include that in our pom.xml&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt;           &amp;lt;groupid&amp;gt; org.terracotta.api&amp;lt;/groupid&amp;gt;&lt;br /&gt;           &amp;lt;artifactid&amp;gt;api&amp;lt;/artifactid&amp;gt;&lt;br /&gt;           &amp;lt;version&amp;gt;1.0.0&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Change the process class to have a count of 4, so we run 4 nodes from our tests.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;plugin&amp;gt;&lt;br /&gt;            ...&lt;br /&gt;                &amp;lt;processes&amp;gt;&lt;br /&gt;                    &amp;lt;process nodename="app" count="4" jvmargs="-Xmx20m"&amp;gt;&lt;br /&gt;                        &amp;lt;classname&amp;gt;org.terracotta.examples.App&lt;br /&gt;                        &amp;lt;/classname&amp;gt;&lt;br /&gt;                    &amp;lt;/process&gt;&lt;br /&gt;               &amp;lt;/processes&gt;&lt;br /&gt;&amp;lt;/plugin&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now that we have our app I want it to be clustered aware. In this example, I'm not going to do anything interesting except print out when node's joins and leaves. So I added the following listener and implementation to my existing App class:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public class App implements DsoClusterListener {&lt;br /&gt;&lt;br /&gt;   @InjectedDsoInstance&lt;br /&gt;private DsoCluster cluster;&lt;br /&gt;&lt;br /&gt;public void registerListener() {&lt;br /&gt;    this.cluster.addClusterListener(this);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;public void nodeJoined(DsoClusterEvent dsoclusterevent) {&lt;br /&gt;    System.out.println("nodeJoined Event about node: " + dsoclusterevent.getNode());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void nodeLeft(DsoClusterEvent dsoclusterevent) {&lt;br /&gt;    System.out.println("nodeLeft Event about node: " + dsoclusterevent.getNode());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void operationsDisabled(DsoClusterEvent dsoclusterevent) {&lt;br /&gt;    //;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void operationsEnabled(DsoClusterEvent dsoclusterevent) {&lt;br /&gt;    //&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And then call registerListener from the main() function:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;App app = new App();&lt;br /&gt;app.registerListener();&lt;br /&gt;app.addMessage("Hello, world");&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;now run the app with the following command to see the node events&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;mvn clean install&lt;br /&gt;mvn tc:run&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Much much more simpler then registering ShutDown hooks. The project is &lt;a href="http://nabiber.googlepages.com/clusterapi-example.zip"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-3440158540216741934?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/3440158540216741934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=3440158540216741934' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/3440158540216741934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/3440158540216741934'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2009/06/terracotta-cluster-events-simple.html' title='Terracotta Cluster Events: A simple example'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-9192816856797176140</id><published>2009-06-20T11:29:00.000-07:00</published><updated>2009-06-23T23:50:15.577-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Terracotta'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Terracotta Integration Module with Maven</title><content type='html'>TIMs or Terracotta Integration Module is a way to package classes and configuration for certain interfaces and products so that you can add terracotta clustering without much effort.  For example, we have a TIM for ehcache so that anyone who uses ehcache can get terracotta clustering just by including the TIM http://forge.terracotta.org/releases/projects/tim-ehcache/&lt;br /&gt;&lt;br /&gt;Sometimes using archetypes in maven is a bit unweilding, so first we are going to check out the correct versions and make sure everything is in place.&lt;br /&gt;&lt;br /&gt;Let's check out the maven-archetype-plugin first:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;svn co http://svn.apache.org/repos/asf/maven/archetype/tags/maven-archetype-2.0-alpha-4/ maven-archetype-2.0-alpha-4&lt;br /&gt;cd maven-archetype-2.0-alpha-4&lt;br /&gt;mvn clean install&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now we want to checkout and install the tim-archetype plugin, is is what builds the directory structure and configuration for our TIM project.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;svn co http://svn.terracotta.org/svn/forge/projects/tim-archetype/trunk/ tim-archetype&lt;br /&gt;cd tim-archetype&lt;br /&gt;mvn clean install&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;To create a TIM project you need to run the following command:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-4:generate \&lt;br /&gt;  -DarchetypeGroupId=org.terracotta.maven.archetypes \&lt;br /&gt;  -DarchetypeArtifactId=tim-archetype \&lt;br /&gt;  -DarchetypeVersion=1.5.0-SNAPSHOT \&lt;br /&gt;  -DremoteRepositories=http://www.terracotta.org/download/reflector/maven2 \&lt;br /&gt;  -DgroupId=org.terracotta.modules.memcached \&lt;br /&gt;  -DartifactId=tim-memcached \&lt;br /&gt;  -Dversion=1.0.0&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;this will prompt you to run the following command:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[INFO] Using property: groupId = org.terracotta.modules.memcached&lt;br /&gt;[INFO] Using property: artifactId = tim-memcached&lt;br /&gt;[INFO] Using property: version = 1.0.0&lt;br /&gt;Define value for property 'package':  org.terracotta.modules.memcached.tim-memcached: : &lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Hit enter or type in the package name you desire and hit enter.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Define value for property 'package':  org.terracotta.modules.memcached.tim-memcached: : &lt;br /&gt;Confirm properties configuration:&lt;br /&gt;groupId: org.terracotta.modules.memcached&lt;br /&gt;artifactId: tim-memcached&lt;br /&gt;version: 1.0.0&lt;br /&gt;package: org.terracotta.modules.memcached.tim-memcached&lt;br /&gt; Y: : &lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Type in 'Y' to finish creating a newly minted TIM.&lt;br /&gt;&lt;br /&gt;All set to go!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-9192816856797176140?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/9192816856797176140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=9192816856797176140' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/9192816856797176140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/9192816856797176140'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2009/06/terracotta-integration-module-with.html' title='Terracotta Integration Module with Maven'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-5049292373088008738</id><published>2008-10-31T01:18:00.000-07:00</published><updated>2008-10-31T01:38:10.961-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='data structures'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Back to Basics</title><content type='html'>When doing a little refactoring on terracotta server code, I was reminded on why the basics ALWAYS matters.&lt;br /&gt;&lt;br /&gt;The server side representation of both ArrayList and LinkedList mapped to a class called ListManagedObjectState.  The underlying data structure for this class was a ArrayList.  We got around to mapping LinkedList to a LinkedListManagedObjectState where the underlying data structure for that class is a LinkedList.&lt;br /&gt;&lt;br /&gt;I wrote a little test and the following where the results:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;ArrayList.add for 50000 objects took 424 ms.&lt;br /&gt;LinkedList.add for 50000 objects took 198 ms.&lt;br /&gt;ArrayList.addFirst for 50000 objects took 906 ms.&lt;br /&gt;LinkedList.addFirst for 50000 objects took 109 ms.&lt;br /&gt;ArrayList.addAt for 50000 took objects 105 ms.&lt;br /&gt;LinkedList.addAt for 50000 took objects 132 ms.&lt;br /&gt;ArrayList.clear for 50000 took objects 127 ms.&lt;br /&gt;LinkedList.clear for 50000 took objects 49 ms.&lt;br /&gt;ArrayList.removeFirst for 50000 took objects 847 ms.&lt;br /&gt;LinkedList.removeFirst for 50000 took objects 70 ms.&lt;br /&gt;ArrayList.remove for 50000 took objects 865 ms.&lt;br /&gt;LinkedList.remove for 50000 took objects 68 ms.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If your mutating a lot more then accessing, then LinkedList is the way to go.&lt;br /&gt;Basics do matter!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-5049292373088008738?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/5049292373088008738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=5049292373088008738' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/5049292373088008738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/5049292373088008738'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2008/10/back-to-basics.html' title='Back to Basics'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-5605910894017025601</id><published>2008-10-30T23:30:00.001-07:00</published><updated>2008-10-31T01:28:53.891-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Terracotta'/><title type='text'>DSO Garbage Collection: YoungGen</title><content type='html'>There are certain apps when clustered using Terracotta that generates short-lived DSO objects and lots of them. Which results in a lot of DSO garbage!&lt;br /&gt;&lt;br /&gt;Taking the existing DSO garbage collector and running it more often will collect these short-lived objects, but the MARK stage could take a long time.  For example, you'll have a Terracotta server array that has DSO objects on the server's cache as well as DSO objects faulted to disk.  When the DSO garbage collector runs, it will fault in objects from the disk during the MARK stage. This may take awhile to run.&lt;br /&gt;&lt;br /&gt;The DSO objects that are short-lived are probably in the server's cache.  This is where YoungGen comes in.  It's the same algorithm, except for the set of objects we are considering as GC Candidates.  Instead of considering all the objects in the system and removing objects that are unreachable.  We only consider the objects on the server's cache and remove objects that we can definitely determine as garbage.&lt;br /&gt;&lt;br /&gt;DSO objects that cannot be collected in YoungGen is the following:&lt;br /&gt;&lt;br /&gt;1. Roots&lt;br /&gt;2. DSO Objects that in the server's cache that is being references by DSO Objects faulted to disk. This is marked in a subset called RememberMe set&lt;br /&gt;3. Objects that are in the cache, but never been flushed to disk (i.e. really new objects).&lt;br /&gt;&lt;br /&gt;enable the following properties and see if YoungGen DSO Garbage Collection works for you:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;l2.objectmanager.dgc.young.enabled = true&lt;br /&gt;l2.objectmanager.dgc.young.frequencyInMillis = 180000&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-5605910894017025601?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/5605910894017025601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=5605910894017025601' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/5605910894017025601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/5605910894017025601'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2008/10/dso-garbage-collection-younggen.html' title='DSO Garbage Collection: YoungGen'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5591335197619669570.post-8465638001479916787</id><published>2008-10-29T17:35:00.000-07:00</published><updated>2008-10-31T01:28:53.891-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Terracotta'/><title type='text'>Terracotta DSO GC Algorithm in a nutshell</title><content type='html'>There maybe a few of you out there (when I mean few, hopefully a few million :)) that maybe interested in how Terracotta collects its Distributed Objects that is no longer in use. Ok here goes...&lt;br /&gt;&lt;br /&gt;Objects that should be collected by DSO Garbage Collection are objects which are no longer referenced by any client (meaning the object has already been GCed locally on every client that held it).  So now that the clients have no more use for this object, its up to the server array to dispose of it (i.e. remove it from the server array cache or terraocotta's persistent storage).&lt;br /&gt;&lt;br /&gt;When DGC kicks in..&lt;br /&gt;&lt;br /&gt;1. It starts monitoring for new objects being created and keep a set of those.  This is used later to rescue GC candidates.&lt;br /&gt;&lt;br /&gt;2. It does its initial mark, which is to get all the ObjectIDs in the system.  And also our roots in the system.  We remove the roots and well as object reachable by roots form GC Candidates set.  The objects that are left are objects that are no longer referenced by anyone&lt;br /&gt;&lt;br /&gt;3. Remember when monitoring new object references was turned on? Now new referenced objects that appeared in our GC Candidate set can be removed from that set.  This means there were new references to those objects while our first marking was going on, so they need to be rescued and not collected anymore.  If after this rescue there are no GC candidates, then GC is complete.&lt;br /&gt;&lt;br /&gt;4. If there are still GC Candidates left, then the system is paused. For us this means pausing our ObjectManager so that new lookup or create requests&lt;br /&gt;goes pending (i.e no new references are created).  We now do another rescue and produce our final GC Candidate set for this GC Cycle. Then new reference monitoring is turned off.&lt;br /&gt;&lt;br /&gt;5. finally we have a have a set to delete and pass that list onto a different thread that will delete the GC Candidates from the ObjectManager in batches.&lt;br /&gt;&lt;br /&gt;Since the delete is staged on a different thread (SEDA arch).  It is possible for another GC Cycle to kick in before all the delete request complete, which can in turn create more objects to delete and life goes on...&lt;br /&gt;&lt;br /&gt;Up next: Young GC Candidates....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5591335197619669570-8465638001479916787?l=javasmith.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javasmith.blogspot.com/feeds/8465638001479916787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5591335197619669570&amp;postID=8465638001479916787' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/8465638001479916787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5591335197619669570/posts/default/8465638001479916787'/><link rel='alternate' type='text/html' href='http://javasmith.blogspot.com/2008/10/terracotta-dso-gc-algorithm-in-nutshell.html' title='Terracotta DSO GC Algorithm in a nutshell'/><author><name>Nabib El-Rahman</name><uri>https://profiles.google.com/115218425756627426333</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-pKI5zwntn7o/AAAAAAAAAAI/AAAAAAAAENk/-nlgiq-oSOQ/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry></feed>
