<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Pragmatic Creativity</title>
	<atom:link href="http://www.vlad-yatsenko.eu/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.vlad-yatsenko.eu</link>
	<description>Software Systems Design and Development in Detail</description>
	<lastBuildDate>Sat, 04 Feb 2012 17:18:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<div id='fb-root'></div>
					<script type='text/javascript'>
						window.fbAsyncInit = function()
						{
							FB.init({appId: null, status: true, cookie: true, xfbml: true});
						};
						(function()
						{
							var e = document.createElement('script'); e.async = true;
							e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
							document.getElementById('fb-root').appendChild(e);
						}());
					</script>	
						<item>
		<title>Why immutable data objects?</title>
		<link>http://www.vlad-yatsenko.eu/2012/02/why-immutable-data-objects/</link>
		<comments>http://www.vlad-yatsenko.eu/2012/02/why-immutable-data-objects/#comments</comments>
		<pubDate>Sat, 04 Feb 2012 16:24:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.vlad-yatsenko.eu/?p=453</guid>
		<description><![CDATA[This may be obvious to many, but apprently not to some. Consider the following example: Car bmw = new Car&#40;&#34;BMW&#34;&#41;; Wheel wheel = new Wheel&#40;&#41;; wheel.setSize&#40;19&#41;; bmw.addWheels&#40;wheel, 4&#41;; save&#40;bmw&#41;; // here the car is not saved as underlying mechanism, say Hibernate, &#160; &#160; &#160; &#160; &#160; &#160;// decided not to flush until later Car trabant [...]]]></description>
			<content:encoded><![CDATA[<p>This may be obvious to many, but apprently not to some. Consider the following example:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">Car bmw <span class="sy0">=</span> <span class="kw1">new</span> Car<span class="br0">&#40;</span><span class="st0">&quot;BMW&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>Wheel wheel <span class="sy0">=</span> <span class="kw1">new</span> Wheel<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>wheel.<span class="me1">setSize</span><span class="br0">&#40;</span>19<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>bmw.<span class="me1">addWheels</span><span class="br0">&#40;</span>wheel, 4<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>save<span class="br0">&#40;</span>bmw<span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// here the car is not saved as underlying mechanism, say Hibernate, </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">// decided not to flush until later</span></p>
<p>Car trabant <span class="sy0">=</span> <span class="kw1">new</span> Car<span class="br0">&#40;</span><span class="st0">&quot;Trabant&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>wheel.<span class="me1">setSize</span><span class="br0">&#40;</span>13<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>trabant.<span class="me1">addWheels</span><span class="br0">&#40;</span>wheel, 4<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>save<span class="br0">&#40;</span>trabant<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>flush<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// here the BMW will be saved with 13 inch wheels</span></div>
</div>
<p>What happens here is that the BMW instead of the expected fancy 19 inch wheels ends up having Trabant size, 13 inch, wheels (not that the car looks odd, it just won&#8217;t go far). If a unit test does not cover this scenario (there would rather be coverage for a simple scenario with one car, as I don&#8217;t believe in perfection of the testing code), the bug may slip into production.</p>
<p>However, this problem can be easily prevented/fixed by introducing immutability.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;"><span class="kw1">class</span> Wheel <span class="br0">&#123;</span></p>
<p><span class="kw1">private</span> <span class="kw1">final</span> size<span class="sy0">;</span></p>
<p><span class="kw1">public</span> Wheel<span class="br0">&#40;</span><span class="kw4">int</span> size<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">this</span>.<span class="me1">size</span> <span class="sy0">=</span> size<span class="sy0">;</span> <span class="br0">&#125;</span></p>
<p><span class="kw1">public</span> <span class="kw4">int</span> getSize<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span> size<span class="sy0">;</span> <span class="br0">&#125;</span></p>
<p><span class="br0">&#125;</span></div>
</div>
<p>This will force a user of the Wheel class to create a new instance every time instead of reusing existing object if a different configuration required.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">Car bmw <span class="sy0">=</span> <span class="kw1">new</span> Car<span class="br0">&#40;</span><span class="st0">&quot;BMW&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>bmw.<span class="me1">addWheels</span><span class="br0">&#40;</span><span class="kw1">new</span> Wheel<span class="br0">&#40;</span>19<span class="br0">&#41;</span>, 4<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>Car trabant <span class="sy0">=</span> <span class="kw1">new</span> Car<span class="br0">&#40;</span><span class="st0">&quot;Trabant&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>save<span class="br0">&#40;</span>bmw<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>trabant.<span class="me1">addWheels</span><span class="br0">&#40;</span><span class="kw1">new</span> Wheel<span class="br0">&#40;</span>13<span class="br0">&#41;</span>, 4<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>save<span class="br0">&#40;</span>trabant<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>flush<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</div>
<p>Note, the code becomes slightly shorter as well.</p>
<p>Just to answer a question why don&#8217;t we do the same with the Car class and leave the `add` method? &#8211; The reason we don&#8217;t need to do this is because the internal state of the car is managed via the Car class interface only. However, be careful if a Car instance may be a non-root part of a different objects hierarchy.</p>
<div class='wpfblike' style='height: 40px;'><fb:like href='http://www.vlad-yatsenko.eu/2012/02/why-immutable-data-objects/' layout='button_count' show_faces='false' width='400' action='like' colorscheme='light' send='false' /></div>]]></content:encoded>
			<wfw:commentRss>http://www.vlad-yatsenko.eu/2012/02/why-immutable-data-objects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hibernate bulk loading: The right way</title>
		<link>http://www.vlad-yatsenko.eu/2012/02/hibernate-bulk-loading-optimization/</link>
		<comments>http://www.vlad-yatsenko.eu/2012/02/hibernate-bulk-loading-optimization/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 01:53:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Enterprise Systems]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[bulk processing]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[oracle coherence]]></category>

		<guid isPermaLink="false">http://www.vlad-yatsenko.eu/?p=457</guid>
		<description><![CDATA[In the current project we are procesing big amount of data in a distributed cache (an Oracle Coherence data grid). This processing relies on some (also big) amount of reference data (1+ million of objects). After application starts the reference data is loaded from an Oracle database into the cache. The data is fairly complex [...]]]></description>
			<content:encoded><![CDATA[<p>In the current project we are procesing big amount of data in a distributed cache (an Oracle Coherence data grid). This processing relies on some (also big) amount of reference data (1+ million of objects). After application starts the reference data is loaded from an Oracle database into the cache. The data is fairly complex and is spread over about 10 tables. Hibernate is used for the ORM mapping. The data model is represented basically by a main class with a set of simple properties and 4 one-to-many, 1-to-5 average, associations. This data is to be loaded, transformed into a different OO form and stored in the cache for effective retrieval later. Guess, how long it would take to do this for 1 million records?.. OK, it depends. There are several approaches, though it&#8217;s obvious that the bottleneck here is the database and Hibernate (reflection is used for O-R transformation) as it can&#8217;t be much parallelized.</p>
<p>1. Load main objects with lazy batch loading of one-to-many associations. One long query for the main objects and multiple (sub)queries for the associations.</p>
<p>2. Load main objects with eager loading of one-to-many associations using join fetch, which means executing single complex query with many outer joins. The performance of such a query, query execution without fetching, is quite poor (20-30 seconds in my case), but it&#8217;s only one query.</p>
<p>One obvious thing to do since we need to deal with a very big number of records (it means we can&#8217;t load everything into memory first and then start processing), is to fetch data via scrollable cursor with some batch size, e.g. 100.</p>
<p>Unfortunately, both approaches have their drawbacks. First approach with regards to the amount of data will execute many queries to fetch associations, say, 1000 000 / 100 (batch size) = 10000 &#8211; this is 100 less, but still lots! In this case, execution time was around 45 minutes (including transformation and putting into cache, but this phases&#8217; time is neglectable).</p>
<p>Second approach is way better in terms of the number of queries (there is only 1! query to execute), and we would expect some significant performance improvement. However, the number of rows to load will be about same, and if we look closer, the amount of data to load and to process by Hibernate is much bigger, because every row will have column from all joint tables: if main table has 10 columns, all 10 values will appear in a row for each combination of associations. Though, in practice this approach showed some improvement, it was insignificant &#8211; it ran in around 30 minutes.</p>
<p>I simply could not accept this very suboptimal performance. So I came up with one more idea&#8230; and it was not about abandoning Hibernate and implementing everything with pure JDBC. The third approach is to have one query per object type: one query for main objects and one query for each of one-to-many associations &#8211; in total 5 quite effective select queries. All these queries should be executed one by one in the beginning and all 5 scrollable resultsets should be processed kvazi-simultaneously in one go. To achieve this, one important requirement should be met by all the queries: they should be ordered by the same key (id of the main object) and have the same set of filters as in the first query. In this case, hibernate mapping of associations is lazy, so we need to take care of populating them in our code while going through the resultsets. This process is illustrated below:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;">iterate MasterResultSet as m<br />
&nbsp; &nbsp; iterate DetailResultSet1 as d1 <span class="kw1">while</span> d1.<span class="me1">key</span> <span class="sy0">=</span> m.<span class="me1">key</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; m.<span class="me1">addDetail1</span><span class="br0">&#40;</span>d1<span class="br0">&#41;</span><br />
&nbsp; &nbsp; end<br />
&nbsp; &nbsp; &#8230;<br />
&nbsp; &nbsp; <span class="me1">iterate</span> DetailResultSetN as dN <span class="kw1">while</span> dN.<span class="me1">key</span> <span class="sy0">=</span> m.<span class="me1">key</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; m.<span class="me1">addDetailN</span><span class="br0">&#40;</span>dN<span class="br0">&#41;</span><br />
&nbsp; &nbsp; end<br />
end</div>
</div>
<p>Using this approach the full bulk loading took only, get ready&#8230; <strong>4 minutes</strong>! This is due to the data being loaded in an optimal way in terms of amount of data, number and complexity of queries, and number of network round trips.</p>
<div class='wpfblike' style='height: 40px;'><fb:like href='http://www.vlad-yatsenko.eu/2012/02/hibernate-bulk-loading-optimization/' layout='button_count' show_faces='false' width='400' action='like' colorscheme='light' send='false' /></div>]]></content:encoded>
			<wfw:commentRss>http://www.vlad-yatsenko.eu/2012/02/hibernate-bulk-loading-optimization/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Quick Shell</title>
		<link>http://www.vlad-yatsenko.eu/2011/12/quick-shell/</link>
		<comments>http://www.vlad-yatsenko.eu/2011/12/quick-shell/#comments</comments>
		<pubDate>Sun, 11 Dec 2011 00:32:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Titbits]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[file management]]></category>
		<category><![CDATA[hosting]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php-shell]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[web console]]></category>
		<category><![CDATA[web shell]]></category>

		<guid isPermaLink="false">http://www.vlad-yatsenko.eu/?p=428</guid>
		<description><![CDATA[You can go straight forward to GitHub, download and start using quick-shell&#8230; then read further. I still like PHP for its simplicity of deployment and management &#8211; just copy files and voila! And for simple webapps you need the cheapest web hosting like the one I have to host a WordPress installation for this blog. [...]]]></description>
			<content:encoded><![CDATA[<p>You can go straight forward to <a href="https://github.com/vladys/quick-shell" target="_blank">GitHub</a>, <a title="php-shell GitHub repository" href="https://github.com/vladys/quick-shell/zipball/master" target="_blank">download</a> and start using quick-shell&#8230; then read further.</p>
<p>I still like PHP for its simplicity of deployment and management &#8211; just copy files and voila! And for simple webapps you need the cheapest web hosting like the one I have to host a WordPress installation for this blog. Everything simple and easy, but&#8230; sloooow! I mean, being restricted to FTP access (normally, you don&#8217;t get SSH access with a cheap PHP hosting) only, transfering files and later managing them can be tedious and ineffective. Fortunately, there&#8217;s a bunch of file management application (written in PHP) that can help you in performing file tasks. But they use your disk space, can be slow and require to much clicking with often page refreshes&#8230; So, ideally would be to have that silver bullet SSH access (though it&#8217;s not ideal as you may not be able to use SSH from everywhere). Just compare, what is faster: to type &#8220;cd &#8230;&#8221; and &#8220;rm &#8230;&#8221; (&#8220;unzip &#8230;&#8221;, &#8220;untar &#8230;&#8221; etc) and press ENTER, or to click through the tree of files with page refresh between each, or even worse &#8211; to perform file manipulations via FTP? For hackers like us, the answer is obvious &#8211; CLI. <img src='http://www.vlad-yatsenko.eu/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
<a href="http://www.vlad-yatsenko.eu/wp-content/uploads/2011/12/ScreenShot022.png"><img class="alignleft wp-image-441" style="margin: 4px 8px;" title="php-shell" src="http://www.vlad-yatsenko.eu/wp-content/uploads/2011/12/ScreenShot022.png" alt="php-shell" width="406" height="162" /></a>So, I though it could be easy to create a web command line application that would execute system commands in my hosting environment&#8230; This thinking resulted in a simple and very lightweight PHP application that gives me all I need in terms of file management on my php hosting &#8211; it&#8217;s called <strong>quick-shell</strong>. Besides that it offers easy ajax-based file upload into a current directory (implemented with jQuery AjaxFileUpload plugin) &#8211; so you can do pretty much everything from your browser. Feel free to download/fork it from <a title="php-shell GitHub repository" href="https://github.com/vladys/quick-shell" target="_blank">GitHub</a>, use it and let me know how you find it.</p>
<p>P.S. <strong><em>Very important!</em></strong> <em>Don&#8217;t forget to create <strong>.htpasswd</strong> file with your password to protect your files from anonymous access.</em></p>
<div class='wpfblike' style='height: 40px;'><fb:like href='http://www.vlad-yatsenko.eu/2011/12/quick-shell/' layout='button_count' show_faces='false' width='400' action='like' colorscheme='light' send='false' /></div>]]></content:encoded>
			<wfw:commentRss>http://www.vlad-yatsenko.eu/2011/12/quick-shell/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hierarchical data fetched in one query</title>
		<link>http://www.vlad-yatsenko.eu/2011/08/hierarchical-data-fetched-in-one-query/</link>
		<comments>http://www.vlad-yatsenko.eu/2011/08/hierarchical-data-fetched-in-one-query/#comments</comments>
		<pubDate>Sun, 14 Aug 2011 16:05:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Titbits]]></category>
		<category><![CDATA[hierarchical query]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.vlad-yatsenko.eu/?p=407</guid>
		<description><![CDATA[This is a very typical situation when you have a hierarchical data structure of the type like forum posts or comments: class Comment &#123; &#160; &#160; long id; &#160; &#160; String comment; &#160; &#160; Comment parent; &#125; Let&#8217;s store it in a relational database (e.g. MySQL). For this we need to create a table: CREATE [...]]]></description>
			<content:encoded><![CDATA[<p>This is a very typical situation when you have a hierarchical data structure of the type like forum posts or comments:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;"><span class="kw1">class</span> Comment <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">long</span> id<span class="sy0">;</span><br />
&nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">String</span></a> comment<span class="sy0">;</span><br />
&nbsp; &nbsp; Comment parent<span class="sy0">;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p>Let&#8217;s store it in a relational database (e.g. MySQL). For this we need to create a table:</p>
<div class="codesnip-container" >
<div class="sql codesnip" style="font-family:monospace;"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> Comment<span class="br0">&#40;</span><br />
&nbsp; id int <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span><span class="sy0">,</span><br />
&nbsp; comment text<span class="sy0">,</span><br />
&nbsp; parent_id int<span class="sy0">,</span><br />
&nbsp; <span class="kw1">FOREIGN</span> <span class="kw1">KEY</span> <span class="br0">&#40;</span>parent_id<span class="br0">&#41;</span> <span class="kw1">REFERENCES</span> Comment<span class="br0">&#40;</span>id<span class="br0">&#41;</span><br />
<span class="br0">&#41;</span>;</div>
</div>
<p>And you need to show it in a tree view, e.g.:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;"><span class="sy0">/</span>Comment#<span class="nu0">1</span><br />
&nbsp; &nbsp;<span class="sy0">/</span>Comment#<span class="nu0">2</span> <span class="br0">&#40;</span>Reply to Comment#<span class="nu0">1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="sy0">/</span>Comment#<span class="nu0">4</span> <span class="br0">&#40;</span>Reply to Comment#<span class="nu0">1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="sy0">/</span>Comment#<span class="nu0">8</span> <span class="br0">&#40;</span>Reply to Comment#<span class="nu0">4</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="sy0">/</span>Comment#<span class="nu0">7</span> <span class="br0">&#40;</span>Reply to Comment#<span class="nu0">1</span><span class="br0">&#41;</span><br />
<span class="sy0">/</span>Comment#<span class="nu0">3</span><br />
<span class="sy0">/</span>Comment#<span class="nu0">5</span><br />
&nbsp; &nbsp;<span class="sy0">/</span>Comment#<span class="nu0">6</span> <span class="br0">&#40;</span>Reply to Comment#<span class="nu0">5</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="sy0">/</span>Comment#<span class="nu0">9</span> <span class="br0">&#40;</span>Reply to Comment#<span class="nu0">6</span><span class="br0">&#41;</span></div>
</div>
<p>You can see that comments added in an arbitrary order (by looking at the comment id sequence).</p>
<p>So how are you going to select all the data to build the tree by SQL means? Standard SQL does not provide hierarchical select feature (like Oracle&#8217;s CONNECT BY). One would probably end up doing multiple queries, which sounds like a very inefficient thing to do (imagine fetching a 10-level depth tree of 1000 comments). Fortunately, there is a better idea. I would say even more: a solution with one simple select query! <img src='http://www.vlad-yatsenko.eu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Excited? It&#8217;s very simple, actually.</p>
<p>The idea is to construct a select statement which will return results sorted in an order we need (say, in the tree above each node is a row in the query result set). On the other hand it is very similar to the structure of directories and files in the filesystem. So, we will use a property of files here, which is the path. When creating a new Comment instance we will set its path, and update when setting a parent Comment:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;"><span class="kw1">class</span> Comment <span class="br0">&#123;</span><br />
&nbsp; &nbsp;<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">String</span></a> path<span class="sy0">;</span><br />
&nbsp; &nbsp;&#8230;<br />
&nbsp; &nbsp;<span class="me1">Comment</span><span class="br0">&#40;</span><span class="kw4">long</span> id<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp;<span class="kw1">this</span>.<span class="me1">id</span> <span class="sy0">=</span> id<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp;<span class="kw1">this</span>.<span class="me1">path</span> <span class="sy0">=</span> <span class="st0">&quot;/&quot;</span> <span class="sy0">+</span> id<span class="sy0">;</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp;<span class="kw4">void</span> setParent<span class="br0">&#40;</span>Comment parent<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">parent</span> <span class="sy0">=</span> parent<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">path</span> <span class="sy0">=</span> <span class="br0">&#40;</span>parent <span class="sy0">==</span> <span class="kw2">null</span> <span class="sy0">?</span> <span class="st0">&quot;&quot;</span> <span class="sy0">:</span> parent.<span class="me1">path</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">&quot;/&quot;</span> <span class="sy0">+</span> id<span class="sy0">;</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p>If we apply this transformation to the example above the data in the table will look like:</p>
<div class="codesnip-container" >
<div class="sql codesnip" style="font-family:monospace;">id &nbsp;parent_id &nbsp;path<br />
<span class="co1">&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</span><br />
1 &nbsp; <span class="kw1">NULL</span> &nbsp; &nbsp; &nbsp; <span class="sy0">/</span>1<br />
2 &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">/</span>1<span class="sy0">/</span>2<br />
3 &nbsp; <span class="kw1">NULL</span> &nbsp; &nbsp; &nbsp; <span class="sy0">/</span>3<br />
4 &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">/</span>1<span class="sy0">/</span>4<br />
5 &nbsp; <span class="kw1">NULL</span> &nbsp; &nbsp; &nbsp; <span class="sy0">/</span><span class="nu0">5</span><br />
<span class="nu0">6</span> &nbsp; <span class="nu0">5</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">/</span><span class="nu0">5</span><span class="sy0">/</span><span class="nu0">6</span><br />
<span class="nu0">7</span> &nbsp; <span class="nu0">1</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">/</span><span class="nu0">1</span><span class="sy0">/</span><span class="nu0">7</span><br />
<span class="nu0">8</span> &nbsp; <span class="nu0">4</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">/</span><span class="nu0">1</span><span class="sy0">/</span><span class="nu0">4</span><span class="sy0">/</span><span class="nu0">8</span><br />
<span class="nu0">9</span> &nbsp; <span class="nu0">6</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">/</span><span class="nu0">5</span><span class="sy0">/</span><span class="nu0">6</span><span class="sy0">/</span><span class="nu0">9</span></div>
</div>
<p>Now we can use the path field to retrieve our comments ordered accordingly. By executing</p>
<div class="codesnip-container" >
<div class="sql codesnip" style="font-family:monospace;"><span class="kw1">SELECT</span> <span class="sy0">*</span> <span class="kw1">FROM</span> comment <span class="kw1">ORDER</span> <span class="kw1">BY</span> path</div>
</div>
<p>we will get this:</p>
<div class="codesnip-container" >
<div class="sql codesnip" style="font-family:monospace;">id &nbsp;parent_id &nbsp;path<br />
<span class="co1">&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</span><br />
1 &nbsp; <span class="kw1">NULL</span> &nbsp; &nbsp; &nbsp; <span class="sy0">/</span>1<br />
2 &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">/</span>1<span class="sy0">/</span>2<br />
4 &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">/</span>1<span class="sy0">/</span>4<br />
8 &nbsp; 4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">/</span>1<span class="sy0">/</span>4<span class="sy0">/</span>8<br />
7 &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">/</span>1<span class="sy0">/</span>7<br />
3 &nbsp; <span class="kw1">NULL</span> &nbsp; &nbsp; &nbsp; <span class="sy0">/</span>3<br />
5 &nbsp; <span class="kw1">NULL</span> &nbsp; &nbsp; &nbsp; <span class="sy0">/</span><span class="nu0">5</span><br />
<span class="nu0">6</span> &nbsp; <span class="nu0">5</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">/</span><span class="nu0">5</span><span class="sy0">/</span><span class="nu0">6</span><br />
<span class="nu0">9</span> &nbsp; <span class="nu0">6</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">/</span><span class="nu0">5</span><span class="sy0">/</span><span class="nu0">6</span><span class="sy0">/</span><span class="nu0">9</span></div>
</div>
<p>The rest is only a matter of formatting the results in order to get nicely looking comments tree output. (Note: the level can be computed as a number of slashes, &#8216;/&#8217;, in the path string).</p>
<p>Also, when using ORM like Hibernate (or JPA in general), you are not forced to use SQL and can get your job done with simple criteria-based or HQL queries.</p>
<p>As a free bonus, you get pagination working properly without extra tweaking as you would have to do in case of multiple queries.</p>
<p>P.S. One piece that is missing in the above example is that the sorting for strings based on numbers will be done in the alphabetical order, e.g. 11 will appear before 2 (which is obviously not what we want). So to fix this problem you can prefix each part of the path with a length of the numbers in characters. It will result in smth like: 12, 211 (or 1.2, 2.11)&#8230;</p>
<div class='wpfblike' style='height: 40px;'><fb:like href='http://www.vlad-yatsenko.eu/2011/08/hierarchical-data-fetched-in-one-query/' layout='button_count' show_faces='false' width='400' action='like' colorscheme='light' send='false' /></div>]]></content:encoded>
			<wfw:commentRss>http://www.vlad-yatsenko.eu/2011/08/hierarchical-data-fetched-in-one-query/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Server-side cache vs client-side cache of prepared statements</title>
		<link>http://www.vlad-yatsenko.eu/2011/08/server-side-vs-client-side-caching-of-prepared-statements/</link>
		<comments>http://www.vlad-yatsenko.eu/2011/08/server-side-vs-client-side-caching-of-prepared-statements/#comments</comments>
		<pubDate>Sat, 13 Aug 2011 13:10:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[jdbc]]></category>
		<category><![CDATA[prepared statement]]></category>

		<guid isPermaLink="false">http://www.vlad-yatsenko.eu/?p=388</guid>
		<description><![CDATA[I&#8217;ve been asked to explain the difference between server-side and client-side caching of database prepared statements. So here is a brief overview. First of all, query plans are not cached on the client-side (it would be a bit foolish, because it would not give any performance boost, because we would have to send the query [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been asked to explain the difference between server-side and client-side caching of database prepared statements. So here is a brief overview.</p>
<p>First of all, query plans are not cached on the client-side (it would be a bit foolish, because it would not give any performance boost, because we would have to send the query plan over the network each time before execution, and it contains more structured information than just a SQL string).</p>
<p>The parsed query plan is only stored on the server side, in a common session cache, so all sessions can reuse it. This comprises the biggest part of queries optimisation by the database server (in terms of usage of both CPU time and memory).</p>
<p>What is cached on the client side? &#8211; It is an identifier of the parsed query (cache then looks like a map of [sql =&gt; id]). Another big difference from the server-side cache is that the client-side cache of prepared statements resides in scope of a session (connection). (I&#8217;m not sure about the rest of the JDBC drivers, but in the Oracle implementation query parameters are also cached, which would create a memory &#8220;leak&#8221; problem when pooled connections are actively used for some period of time, hence they don&#8217;t get closed, and the cache doesn&#8217;t get released.)</p>
<p>In general, the prepared statement execution looks like (in terms on commands sent to the database server):</p>
<p>1. id = PREPARE (sql) &lt;- here on the server there will be an attempt to get the query plan from the cache.<br />
2. EXECUTE (id, params1)<br />
3. (optional) EXECUTE (id, params2) &#8230;</p>
<p>You can see that PREPARE for the same query is executed only once throughout the session (the lifetime of the connection). Considering that in most scenarios connection pool is used, it allows you to save relevant amount of time by not performing an additional PREPARE request on the network before each consecutive EXECUTE.</p>
<div class='wpfblike' style='height: 40px;'><fb:like href='http://www.vlad-yatsenko.eu/2011/08/server-side-vs-client-side-caching-of-prepared-statements/' layout='button_count' show_faces='false' width='400' action='like' colorscheme='light' send='false' /></div>]]></content:encoded>
			<wfw:commentRss>http://www.vlad-yatsenko.eu/2011/08/server-side-vs-client-side-caching-of-prepared-statements/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Optimistic locking vs Pessimistic locking explained concisely</title>
		<link>http://www.vlad-yatsenko.eu/2011/07/optimistic-locking-vs-pessimistic-locking-explained-concisely/</link>
		<comments>http://www.vlad-yatsenko.eu/2011/07/optimistic-locking-vs-pessimistic-locking-explained-concisely/#comments</comments>
		<pubDate>Wed, 06 Jul 2011 14:38:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Design patterns]]></category>
		<category><![CDATA[optomistic locking]]></category>
		<category><![CDATA[pessimistic locking]]></category>

		<guid isPermaLink="false">http://www.vlad-yatsenko.eu/?p=381</guid>
		<description><![CDATA[I&#8217;ve found this funny and interesting explanation of Optimistic vs Pessimistic locking through the analogy with the toilet door and could not stand not to share Optimistic locking is like leaving the door to the toilet open: you have a number of toilets, select one, and you are optimistic that nobody will come to use [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve found this funny and interesting explanation of Optimistic vs Pessimistic locking through the analogy with the toilet door and could not stand not to share <img src='http://www.vlad-yatsenko.eu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<blockquote><p><strong>Optimistic locking</strong> is like leaving the door to the toilet open: you have a number of toilets, select one, and you are optimistic that nobody will come to use the same toilet, too. If someome comes, it will of course be embarassing, an exception is raised, and he must abort his try, but you hope that these conflicts are the execption.</p>
<p><strong>Pessimistic locking</strong> is like always locking the door to the toilet: although there are a number of different toilets, you are expecting every time that somebody else will come to use one, too, and that the only safe option is to lock all toilet doors (which corresponds to page locking). If someone comes and wants to use a toilet, he cannot enter and must wait before the locked door.</p></blockquote>
<p>Found at <a title="Optimistic vs. Pessimistic Locking" href="http://4loc.wordpress.com/2009/04/25/optimistic-vs-pessimistic-locking/">Optimistic vs. Pessimistic Locking</a>.</p>
<div class='wpfblike' style='height: 40px;'><fb:like href='http://www.vlad-yatsenko.eu/2011/07/optimistic-locking-vs-pessimistic-locking-explained-concisely/' layout='button_count' show_faces='false' width='400' action='like' colorscheme='light' send='false' /></div>]]></content:encoded>
			<wfw:commentRss>http://www.vlad-yatsenko.eu/2011/07/optimistic-locking-vs-pessimistic-locking-explained-concisely/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mod-pagespeeding up your site</title>
		<link>http://www.vlad-yatsenko.eu/2011/07/mod-pagespeeding-up-your-site/</link>
		<comments>http://www.vlad-yatsenko.eu/2011/07/mod-pagespeeding-up-your-site/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 00:03:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[auto versioning]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[mod_pagespeed]]></category>

		<guid isPermaLink="false">http://www.vlad-yatsenko.eu/?p=369</guid>
		<description><![CDATA[A beautiful and simple way to speed up your site without applying any magic in your code is to install mod_pagespeed module for Apache web server. Installation: Create /etc/yum.repos.d/mod-pagespeed.repo yum config file for mod_pagespeed with the following content: [mod-pagespeed] name=mod-pagespeed baseurl=http://dl.google.com/linux/mod-pagespeed/rpm/stable/x86_64 enabled=1 gpgcheck=0 Then install mod-pagespeed: yum install mod-pagespeed Restart httpd service to get it [...]]]></description>
			<content:encoded><![CDATA[<p>A beautiful and simple way to speed up your site without applying any magic in your code is to install <a href="http://code.google.com/speed/page-speed/docs/module.html">mod_pagespeed</a> module for Apache web server.</p>
<p><strong>Installation</strong>:</p>
<ul>
<li>Create <em>/etc/yum.repos.d/mod-pagespeed.repo</em> yum config file for mod_pagespeed with the following content:
<div class="codesnip-container" >[mod-pagespeed]<br />
name=mod-pagespeed<br />
baseurl=http://dl.google.com/linux/mod-pagespeed/rpm/stable/x86_64<br />
enabled=1<br />
gpgcheck=0</div>
</li>
<li>Then install mod-pagespeed:
<div class="codesnip-container" >yum install mod-pagespeed</div>
</li>
<li>Restart httpd service to get it all working:
<div class="codesnip-container" >service httpd restart</div>
</li>
</ul>
<p><em>Later, I will update this post with the comparison of performance with and without mod_pagespeed (with <a href="https://addons.mozilla.org/en-US/firefox/addon/lori-life-of-request-info/">lori add-on</a>).</em></p>
<div class='wpfblike' style='height: 40px;'><fb:like href='http://www.vlad-yatsenko.eu/2011/07/mod-pagespeeding-up-your-site/' layout='button_count' show_faces='false' width='400' action='like' colorscheme='light' send='false' /></div>]]></content:encoded>
			<wfw:commentRss>http://www.vlad-yatsenko.eu/2011/07/mod-pagespeeding-up-your-site/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Empty img src or Freaking repeated request problem</title>
		<link>http://www.vlad-yatsenko.eu/2011/04/empty-img-src-or-freaking-repeated-request-problem/</link>
		<comments>http://www.vlad-yatsenko.eu/2011/04/empty-img-src-or-freaking-repeated-request-problem/#comments</comments>
		<pubDate>Wed, 27 Apr 2011 22:57:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Titbits]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[empty src]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[repeated request]]></category>

		<guid isPermaLink="false">http://www.vlad-yatsenko.eu/?p=352</guid>
		<description><![CDATA[Hi! This is a victorious and quick post I have to make. (: And here is why. It took me two days of debugging and googling to find out the cause of a freaking problem: browser kept up sending same request for one of the pages of a Grails app I am working on now. [...]]]></description>
			<content:encoded><![CDATA[<p>Hi! This is a victorious and quick post I have to make. (: And here is why. It  took me two days of debugging and googling to find out the cause of a  freaking problem: browser kept up sending same request for one of the  pages of a Grails app I am working on now. The reason is an empty &#8216;src&#8217;  attribute of an &lt;img&gt; element (actually, it can be any element  referring to loaded resource like a .js or .css file or any media  content). You can read more about the problem itself here: <a href="http://www.nczonline.net/blog/2009/11/30/empty-image-src-can-destroy-your-site/">Empty image src can destroy your site</a>.  I myself would probably never face this problem if didn&#8217;t have captcha  (generated for each request to the problematic URL) and an optional  image.</p>
<p>And here&#8217;s the solution:<br />
1) in server code</p>
<div class="codesnip-container" >&lt;img ${ !url?:&#8217;src=&#8221;$url&#8221;&#8216; }/&gt;</div>
<p>(in Grails terms meaning: don&#8217;t render the &#8216;src&#8217; attribute if the url is empty)</p>
<p>2) in client (javascript) code:</p>
<div class="codesnip-container" >imgElement.src = null; // don&#8217;t set img.src to empty string, though null is fine</div>
<p>So first, never ever leave your &#8216;src&#8217; attribute empty! And second, never  ever set &#8216;src&#8217; value to empty string programatically or by any other  means. Third, it&#8217;s ok to do this when it&#8217;s officially fixed either html5  is fully supported by all major browsers (hopefully).</p>
<p>Have a good one!</p>
<div class='wpfblike' style='height: 40px;'><fb:like href='http://www.vlad-yatsenko.eu/2011/04/empty-img-src-or-freaking-repeated-request-problem/' layout='button_count' show_faces='false' width='400' action='like' colorscheme='light' send='false' /></div>]]></content:encoded>
			<wfw:commentRss>http://www.vlad-yatsenko.eu/2011/04/empty-img-src-or-freaking-repeated-request-problem/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Plesk + Apache + mod_jk + Tomcat = Good relationship</title>
		<link>http://www.vlad-yatsenko.eu/2011/04/plesk-apache-mod_jk-tomcat-good-relationship/</link>
		<comments>http://www.vlad-yatsenko.eu/2011/04/plesk-apache-mod_jk-tomcat-good-relationship/#comments</comments>
		<pubDate>Sun, 24 Apr 2011 06:26:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[EuroVPS]]></category>
		<category><![CDATA[hosting]]></category>
		<category><![CDATA[mod_jk]]></category>
		<category><![CDATA[Plesk]]></category>
		<category><![CDATA[Tomcat 6]]></category>
		<category><![CDATA[Tomcat 7]]></category>

		<guid isPermaLink="false">http://www.vlad-yatsenko.eu/?p=317</guid>
		<description><![CDATA[1. Create an application/domain user: $ useradd supersite 2. Install Tomcat by copying and unzipping an archive: $ wget http://apache.mirror.anlx.net/tomcat/tomcat-7/v7.0.12/bin/apache-tomcat-7.0.12.zip $ unzip apache-tomcat-7.0.12.zip -d tomcat7 3. Create a service configuration for Tomcat 7: $ cd /etc/init.d $ edit tomcat7-supersite #!/bin/bash # # tomcat7-supersite # # chkconfig: &#8211; 81 21 # # description: Tomcat 7 (supersite) [...]]]></description>
			<content:encoded><![CDATA[<p>1. Create an application/domain user:</p>
<div class="codesnip-container" >$ useradd supersite</div>
<p>2. Install Tomcat by copying and unzipping an archive:</p>
<div class="codesnip-container" >$ wget http://apache.mirror.anlx.net/tomcat/tomcat-7/v7.0.12/bin/apache-tomcat-7.0.12.zip<br />
$ unzip apache-tomcat-7.0.12.zip -d tomcat7</div>
<p>3. Create a service configuration for Tomcat 7:</p>
<div class="codesnip-container" >$ cd /etc/init.d<br />
$ edit tomcat7-supersite</div>
<div class="codesnip-container" >
<div class="bash codesnip" style="font-family:monospace;"><span class="co0">#!/bin/bash</span><br />
<span class="co0">#</span><br />
<span class="co0"># tomcat7-supersite</span><br />
<span class="co0">#</span><br />
<span class="co0"># chkconfig: &#8211; 81 21</span><br />
<span class="co0">#</span><br />
<span class="co0"># description: Tomcat 7 (supersite) startup script</span><br />
<span class="co0">#</span></p>
<p><span class="co0"># Source function library.</span><br />
. <span class="sy0">/</span>etc<span class="sy0">/</span>init.d<span class="sy0">/</span>functions</p>
<p><span class="co0">#Test root privilages</span><br />
<span class="re2">RETVAL</span>=<span class="re4">$?</span><br />
<span class="kw3">test</span> <span class="re1">$EUID</span> = 0 &nbsp;<span class="sy0">||</span> <span class="kw3">exit</span> 4</p>
<p><span class="re2">CATALINA_HOME</span>=<span class="sy0">/</span>home<span class="sy0">/</span>supersite<span class="sy0">/</span>tomcat7<br />
<span class="re2">JAVA_HOME</span>=<span class="sy0">/</span>usr<span class="sy0">/</span>lib<span class="sy0">/</span>jvm<span class="sy0">/</span>jdk1.6.0_24<br />
<span class="re2">TOMCAT_OWNER</span>=supersite<br />
<span class="re2">CATALINA_PID</span>=<span class="re1">$CATALINA_HOME</span><span class="sy0">/</span>bin<span class="sy0">/</span>tomcat.pid</p>
<p><span class="kw3">export</span> CATALINA_HOME<br />
<span class="kw3">export</span> JAVA_HOME<br />
<span class="kw3">export</span> TOMCAT_OWNER<br />
<span class="kw3">export</span> CATALINA_PID</p>
<p>start<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">rm</span> <span class="re5">-f</span> <span class="re1">$CATALINA_PID</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="re5">-n</span> <span class="st0">&quot;Starting Tomcat for <span class="es2">$TOMCAT_OWNER</span>: &nbsp;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">su</span> <span class="re1">$TOMCAT_OWNER</span> <span class="re5">-c</span> <span class="re1">$CATALINA_HOME</span><span class="sy0">/</span>bin<span class="sy0">/</span>startup.sh<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">sleep</span> 2<br />
<span class="br0">&#125;</span></p>
<p>stop<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="re5">-n</span> <span class="st0">&quot;Stopping Tomcat for <span class="es2">$TOMCAT_OWNER</span>: &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">su</span> <span class="re1">$TOMCAT_OWNER</span> <span class="re5">-c</span> <span class="re1">$CATALINA_HOME</span><span class="sy0">/</span>bin<span class="sy0">/</span>shutdown.sh<br />
<span class="br0">&#125;</span><br />
restart<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co0"># Restart</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; stop<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Sleeping for 20 seconds &#8230;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">sleep</span> 20<br />
&nbsp; &nbsp; &nbsp; &nbsp; start<br />
<span class="br0">&#125;</span></p>
<p>status<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re2">RETVAL</span>=<span class="st0">&quot;1&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re5">-f</span> <span class="st0">&quot;<span class="es3">${CATALINA_PID}</span>&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">read</span> kpid <span class="sy0">&lt;</span> <span class="re1">$CATALINA_PID</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> checkpid <span class="re1">$kpid</span> 2<span class="sy0">&gt;&amp;</span><span class="nu0">1</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;$0 is already running (<span class="es3">${kpid}</span>)&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">RETVAL</span>=<span class="st0">&quot;0&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;lock file found but no process running for pid <span class="es2">$kpid</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fi</span><br />
&nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">pid</span>=<span class="st0">&quot;<span class="es4">$(pgrep -u ${TOMCAT_OWNER} java)</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re5">-n</span> <span class="st0">&quot;<span class="es2">$pid</span>&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;$0 running (<span class="es3">${pid}</span>) but no PID file exists&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">RETVAL</span>=<span class="st0">&quot;0&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;$0 is stopped&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fi</span><br />
&nbsp; &nbsp; <span class="kw1">fi</span><br />
&nbsp; &nbsp; <span class="kw3">return</span> <span class="re1">$RETVAL</span><br />
<span class="br0">&#125;</span></p>
<p><span class="co0"># See how we were called.</span><br />
<span class="kw1">case</span> <span class="st0">&quot;$1&quot;</span> <span class="kw1">in</span><br />
&nbsp; start<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; start<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span><br />
&nbsp; stop<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; stop<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span><br />
&nbsp; restart<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; restart<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span><br />
&nbsp; status<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; status<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span><br />
&nbsp; version<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; parseOptions<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;<span class="es3">${JAVA_HOME}</span>/bin/java&quot;</span> \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re5">-classpath</span> <span class="st0">&quot;<span class="es3">${CATALINA_HOME}</span>/server/lib/catalina.jar&quot;</span> \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; org.apache.catalina.util.ServerInfo<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">;;</span><br />
&nbsp; <span class="sy0">*</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> $<span class="st0">&quot;Usage: tomcat {start|stop|restart}&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">exit</span> 1<br />
<span class="kw1">esac</span></p>
<p><span class="kw3">exit</span> <span class="re1">$RETVAL</span></div>
</div>
<p>4. Verify the service config with commands:</p>
<div class="codesnip-container" >$ service tomcat7-supersite start<br />
$ service tomcat7-supersite status<br />
$ service tomcat7-supersite restart<br />
$ service tomcat7-supersite stop</div>
<p>5. Configure an AJP connector in $TOMCAT_HOME/conf/service.xml:</p>
<div class="codesnip-container" >
<div class="xml codesnip" style="font-family:monospace;"><span class="sc3"><span class="re1">&lt;Connector</span> <span class="re0">port</span>=<span class="st0">&quot;8010&quot;</span> <span class="re0">protocol</span>=<span class="st0">&quot;AJP/1.3&quot;</span> <span class="re0">redirectPort</span>=<span class="st0">&quot;8443&quot;</span> <span class="re0">URIEncoding</span>=<span class="st0">&quot;UTF-8&quot;</span><span class="re2">/&gt;</span></span></div>
</div>
<p>If you don&#8217;t want your Tomcat to be exposed for direct HTTP requests comment out HTTP/1.1 connector section.</p>
<p>6. Configure Tomcat to respond to the supersite domain (e.g., supersite.com):</p>
<div class="codesnip-container" >
<div class="xml codesnip" style="font-family:monospace;"><span class="sc3"><span class="re1">&lt;Engine</span> <span class="re0">name</span>=<span class="st0">&quot;Catalina&quot;</span> <span class="re0">defaultHost</span>=<span class="st0">&quot;localhost&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Host</span> <span class="re0">name</span>=<span class="st0">&quot;supersite.com&quot;</span> <span class="re0">appBase</span>=<span class="st0">&quot;webapps&quot;</span> <span class="re0">unpackWARs</span>=<span class="st0">&quot;true&quot;</span> <span class="re0">autoDeploy</span>=<span class="st0">&quot;true&quot;</span> <span class="re0">xmlValidation</span>=<span class="st0">&quot;false&quot;</span> <span class="re0">xmlNamespaceAware</span>=<span class="st0">&quot;false&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;Alias<span class="re2">&gt;</span></span></span>www.supersite.com<span class="sc3"><span class="re1">&lt;/Alias<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Host<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/Engine<span class="re2">&gt;</span></span></span></div>
</div>
<p>7. Update your mod_jk to the latest version by getting an appropriate for your system mod_jk*.so file from http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/:</p>
<div class="codesnip-container" >$ cd /etc/httpd/modules<br />
$ mv mod_jk.so mod_jk.bk<br />
$ wget -O mod_jk.so http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/linux/jk-1.2.31/x86_64/mod_jk-1.2.31-httpd-2.2.x.so<br />
$ chmod 755 mod_jk.so</div>
<p>8. Create a new domain (supersite.com) using Plesk panel.</p>
<p>9. Configure your Apache to use mod_jk for the supersite domain:</p>
<div class="codesnip-container" >$ cd /var/www/vhosts/supersite.com/conf<br />
$ edit vhost.conf</div>
<div class="codesnip-container" >ServerAlias www.supersite.com<br />
JkMount /* ajp-veneve</div>
<p>Then execute the following to ask Plesk to include your new vhost.conf into httpd.include:</p>
<div class="codesnip-container" >$ /usr/local/psa/admin/sbin/websrvmng -u &#8211;vhost-name=supersite.com</div>
<p>Create jk.conf:</p>
<div class="codesnip-container" >$ cd /etc/httpd/conf.d<br />
$ edit jk.conf</div>
<div class="codesnip-container" >LoadModule jk_module /usr/lib64/httpd/modules/mod_jk.so<br />
JkWorkersFile conf/workers.properties<br />
JkLogFile logs/mod_jk.log<br />
JkLogLevel info<br />
JkLogStampFormat &#8220;[%a %b %d %H:%M:%S %Y]&#8220;</div>
<p>Create workers.properties in /etc/httpd/conf:</p>
<div class="codesnip-container" >worker.list=ajp-supersite<br />
worker.ajp-supersite.port=8010<br />
worker.ajp-supersite.host=localhost<br />
worker.ajp-supersite.type=ajp13</div>
<p>10. Restart Apache:</p>
<div class="codesnip-container" >$ service httpd restart</div>
<p>11. Deploy you application to Tomcat by copying war file to /home/supersite/tomcat7/webapps. You can also deploy your application as a ROOT application by either renaming the war file to ROOT.war or replacing content of the existing ROOT directory with the war content.</p>
<p>12. Verify if the Tomcat it responding by going to http://supersite.com (also verify http://www.supersite.com).</p>
<p>13. Check Tomcat logs in $TOMCAT_HOME/logs/catalina.out if your application failed to start. This will help to diagnose a possible issue with the application itself.</p>
<div class='wpfblike' style='height: 40px;'><fb:like href='http://www.vlad-yatsenko.eu/2011/04/plesk-apache-mod_jk-tomcat-good-relationship/' layout='button_count' show_faces='false' width='400' action='like' colorscheme='light' send='false' /></div>]]></content:encoded>
			<wfw:commentRss>http://www.vlad-yatsenko.eu/2011/04/plesk-apache-mod_jk-tomcat-good-relationship/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ruthless but Fair Task Executor</title>
		<link>http://www.vlad-yatsenko.eu/2011/03/ruthless-but-fair-task-executor/</link>
		<comments>http://www.vlad-yatsenko.eu/2011/03/ruthless-but-fair-task-executor/#comments</comments>
		<pubDate>Mon, 28 Mar 2011 23:42:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[java.util.concurrency]]></category>
		<category><![CDATA[multi-threaded]]></category>

		<guid isPermaLink="false">http://www.vlad-yatsenko.eu/?p=257</guid>
		<description><![CDATA[Goal: To implement fair mechanism for execution of tasks in parallel with fair usage of resources by each task. Proposed implementation is going to be ruthless so as fairly long running tasks will be simply killed, so they don&#8217;t block execution of other tasks in the queue. Ingridients: WatchedFutureTask &#8211; a monitored task, which should [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.vlad-yatsenko.eu/wp-content/uploads/2011/03/Facebook-Execution.jpg" alt="Facebook execution" title="" width="240" height="240" class="alignright size-full wp-image-286" />Goal: To implement fair mechanism for execution of tasks in parallel with fair usage of resources by each task.<br />
Proposed implementation is going to be ruthless so as fairly long running tasks will be simply killed, so they don&#8217;t block execution of other tasks in the queue.<br />
<br/><br/><br/><br/><br/><br />
Ingridients: <strong>WatchedFutureTask</strong> &#8211; a monitored task, which should rather be nimble and swift.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;"><span class="kw1">public</span> <span class="kw1">class</span> WatchedFutureTask <span class="kw1">extends</span> FutureTask<span class="sy0">&lt;</span>Object<span class="sy0">&gt;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw4">long</span> startTime<span class="sy0">;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">public</span> WatchedFutureTask<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Arunnable+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Runnable</span></a> runnable<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span>runnable, <span class="kw2">null</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">void</span> run<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; startTime <span class="sy0">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">System</span></a>.<span class="me1">currentTimeMillis</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span>.<span class="me1">run</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">boolean</span> isTimedOut<span class="br0">&#40;</span><span class="kw4">int</span> timeout<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="sy0">!</span>isCancelled<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <span class="sy0">!</span>isDone<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">System</span></a>.<span class="me1">currentTimeMillis</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">&gt;</span> <span class="br0">&#40;</span>startTime <span class="sy0">+</span> timeout<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p><strong>TaskMonitor</strong> &#8211; the ruthless and thread-safe killer.</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;"><span class="kw1">public</span> <span class="kw1">class</span> TaskMonitor <span class="kw1">extends</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Athread+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Thread</span></a> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw1">final</span> Queue<span class="sy0">&lt;</span>WatchedFutureTask<span class="sy0">&gt;</span> runningTasks <span class="sy0">=</span> <span class="kw1">new</span> ConcurrentLinkedQueue<span class="sy0">&lt;</span>WatchedFutureTask<span class="sy0">&gt;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">private</span> <span class="kw1">final</span> <span class="kw4">long</span> timeout<span class="sy0">;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">public</span> TaskMonitor<span class="br0">&#40;</span><span class="kw4">long</span> timeout<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">timeout</span> <span class="sy0">=</span> timeout<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">void</span> watch<span class="br0">&#40;</span>WatchedFutureTask task<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; runningTasks.<span class="me1">add</span><span class="br0">&#40;</span>task<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">void</span> run<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="sy0">!</span>isInterrupted<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span>Iterator<span class="sy0">&lt;</span>WatchedFutureTask<span class="sy0">&gt;</span> it <span class="sy0">=</span> runningTasks.<span class="me1">iterator</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> it.<span class="me1">hasNext</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WatchedFutureTask task <span class="sy0">=</span> it.<span class="me1">next</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>task.<span class="me1">isTimedOut</span><span class="br0">&#40;</span>timeout<span class="br0">&#41;</span><span class="br0">&#41;</span> task.<span class="me1">cancel</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>task.<span class="me1">isDone</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">||</span> task.<span class="me1">isCancelled</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> it.<span class="me1">remove</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Athread+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Thread</span></a>.<span class="me1">sleep</span><span class="br0">&#40;</span>5000<span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// run every 5 second</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Ainterruptedexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">InterruptedException</span></a> e<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// should exit naturally</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p><strong>ExecutorService</strong> provided by <strong>java.util.concurrent</strong> package.<br />
And now putting it all together we have got <strong>TaskExecutor</strong>:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;"><span class="kw1">public</span> <span class="kw1">class</span> TaskExecutor <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">private</span> TaskMonitor monitor<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">private</span> ExecutorService executor<span class="sy0">;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">public</span> TaskExecutor<span class="br0">&#40;</span><span class="kw4">int</span> threadPoolSize, <span class="kw4">long</span> taskTimeout<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ExecutorService executor <span class="sy0">=</span> Executors.<span class="me1">newFixedThreadPool</span><span class="br0">&#40;</span>threadPoolSize<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; monitor <span class="sy0">=</span> <span class="kw1">new</span> TaskMonitor<span class="br0">&#40;</span>taskTimeout<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; monitor.<span class="me1">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">public</span> <span class="kw4">void</span> submit<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Arunnable+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Runnable</span></a> task<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; WatchedFutureTask wtask <span class="sy0">=</span> <span class="kw1">new</span> WatchedFutureTask<span class="br0">&#40;</span>task<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; executor.<span class="me1">execute</span><span class="br0">&#40;</span>wtask<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; monitor.<span class="me1">watch</span><span class="br0">&#40;</span>wtask<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p>Leveraging capability of <strong>Future<T></strong> to hold task execution result (of type T), we could eloborate and arrange collection of the tasks execution results. To achieve this, you would replace usages of <strong>Runnable</strong> with usages of <strong>Callable<T></strong> and implement appropriate logic to store the outcomes.</p>
<div class='wpfblike' style='height: 40px;'><fb:like href='http://www.vlad-yatsenko.eu/2011/03/ruthless-but-fair-task-executor/' layout='button_count' show_faces='false' width='400' action='like' colorscheme='light' send='false' /></div>]]></content:encoded>
			<wfw:commentRss>http://www.vlad-yatsenko.eu/2011/03/ruthless-but-fair-task-executor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

