<?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'><id>tag:blogger.com,1999:blog-1017709164693452092</id><updated>2009-09-28T22:46:10.032-06:00</updated><title type='text'>Andy Grove's Blog</title><subtitle type='html'>Andy Grove's thoughts on software development and technology in general.</subtitle><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default?start-index=26&amp;max-results=25'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.codefutures.com/weblog/andygrove/atom.xml'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>46</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-3241360746232517479</id><published>2009-09-15T15:28:00.002-06:00</published><updated>2009-09-15T15:34:59.658-06:00</updated><title type='text'>Snow Leopard + IntelliJ issues</title><content type='html'>Since upgrading to Snow Leopard and restoring Apple Java 1.5.1 from backup I've been having tons of stability issues with IntelliJ 8.1.3 and I finally got this resolved today. It seems that there is a reason why Apple chose to remove their 1.5.1 version from Snow Leopard after all. I think there are some compatibility issues with the new OS version.&lt;br /&gt;&lt;br /&gt;Since modifying IntelliJ's startup configuration to use Java 1.6 instead of 1.5 and clearing out the old caches, all the stability issues seem to have gone away.&lt;br /&gt;&lt;br /&gt;I modified /Applications/IntelliJ IDEA 8.1.app/Contents/Info.plist as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;key&amp;gt;JVMVersion&amp;lt;/key&amp;gt;&lt;br /&gt;&amp;lt;string&amp;gt;1.6*&amp;lt;/string&amp;gt;&lt;br /&gt;&amp;lt;key&amp;gt;JVMArchs&amp;lt;/key&amp;gt;&lt;br /&gt;&amp;lt;string&amp;gt;x86_64&amp;lt;/string&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-3241360746232517479?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/3241360746232517479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=3241360746232517479' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/3241360746232517479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/3241360746232517479'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2009/09/snow-leopard-intellij-issues.html' title='Snow Leopard + IntelliJ issues'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-1985465048411638066</id><published>2009-09-14T09:00:00.003-06:00</published><updated>2009-09-14T09:03:49.126-06:00</updated><title type='text'>MySQL Replication HOWTO</title><content type='html'>I've just published a short video showing how to set up MySQL replication between a single master and slave at &lt;a href="http://www.codefutures.com/mysql-replication-howto"&gt;http://www.codefutures.com/mysql-replication-howto&lt;/a&gt;. This video also demonstrates transaction loss in the case of a master server failure. &lt;br /&gt;&lt;br /&gt;When we built dbShards we needed a reliable replication solution so that we could failover in the case of a single node failing but without losing any transactions, which is why we had to build our own reliable replication technology once we had ruled out other replication solutions (including regular MySQL replication and DRBD).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-1985465048411638066?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/1985465048411638066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=1985465048411638066' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/1985465048411638066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/1985465048411638066'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2009/09/mysql-replication-howto.html' title='MySQL Replication HOWTO'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-7100478640200983622</id><published>2009-09-02T08:14:00.002-06:00</published><updated>2009-09-02T08:20:19.208-06:00</updated><title type='text'>Snow Leopard ate my Java</title><content type='html'>Like many Mac users, I upgraded to Snow Leopard on Friday and overall it was a good experience. Some aspects of daily use are definitely 'snappier' now and I do seem to have a good deal more disk space available than before. I had to uninstall some HP software to get my printer/scanner working smoothly but that was the only glitch with peripherals.&lt;br /&gt;&lt;br /&gt;I was somewhat surprised to find that I could no longer compile some of my Java projects though. It turns out that Snow Leopard includes Java 1.3 and 1.6 but not 1.5. It actually creates symlinks from the 1.5/1.5.0 directories to the 1.6.0 directory. Unfortunately Java 1.6 is not backwardly compatible with 1.5 (well, the language mostly is, but there are significant differences in some APIs).&lt;br /&gt;&lt;br /&gt;If you are impacted by this issue then the good news is that it is very simple to resolve. You simply need to restore the 1.5.0 directory from your backup. This was very simple with time machine, and it was good to have a reason to finally try out a time machine restore.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-7100478640200983622?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/7100478640200983622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=7100478640200983622' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/7100478640200983622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/7100478640200983622'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2009/09/snow-leopard-ate-my-java.html' title='Snow Leopard ate my Java'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-5345302841749732865</id><published>2009-04-24T09:11:00.002-06:00</published><updated>2009-04-24T09:19:45.504-06:00</updated><title type='text'>MySQL Conference 2009</title><content type='html'>I've just returned from the MySQL Conference 2009 in Santa Clara where CodeFutures launched the beta of &lt;a href="http://www.codefutures.com/dbshards-cloud/"&gt;dbShards Cloud Edition&lt;/a&gt;. It was great to see such a good turnout at the show (I heard that there were between 1,500 and 2,000 attendees) despite the state of the economy. It was also great to see how many companies are either implementing sharding or considering sharding for their applications. There seems to be much greater awareness of sharding than there was just one year ago and people I met understood that a shared-nothing approach offers the best possible performance and scalability. The one common concern about adopting sharding is that it introduces complexity into the application, but using a packaged solution such as &lt;a href="http://www.codefutures.com/dbshards/"&gt;dbShards&lt;/a&gt; this is much less of an issue.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-5345302841749732865?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/5345302841749732865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=5345302841749732865' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/5345302841749732865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/5345302841749732865'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2009/04/mysql-conference-2009.html' title='MySQL Conference 2009'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-4010863994940597851</id><published>2009-04-14T17:18:00.002-06:00</published><updated>2009-04-14T17:23:47.765-06:00</updated><title type='text'>CodeFutures @ MySQL Conference 2009</title><content type='html'>CodeFutures will be exhibiting at this year's MySQL conference. Visit us on the exhibition floor Tuesday through Thursday next week to see a demonstration of dbShards.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-4010863994940597851?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/4010863994940597851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=4010863994940597851' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/4010863994940597851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/4010863994940597851'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2009/04/codefutures-mysql-conference-2009.html' title='CodeFutures @ MySQL Conference 2009'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-4129906490132161457</id><published>2009-01-25T11:48:00.006-07:00</published><updated>2009-01-25T12:34:35.076-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby example'/><title type='text'>Ruby/Webrick File upload using multipart/form-data</title><content type='html'>One of the challenges I'm running into with Ruby is that there isn't the same level of reference documentation as there is in Java. It took me far too long to work out how to implement HTTP multipart file upload in Ruby so I'm posting the code here in the hope that it is useful for others.&lt;br /&gt;&lt;br /&gt;The following Ruby source is for a web server with a file upload servlet that accepts multpart/form-data file uploads.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="comment"&gt;#!/usr/local/bin/ruby&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;webrick&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;stringio&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;WEBrick&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="ident"&gt;s&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;HTTPServer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="symbol"&gt;:Port&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;8090&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;FileUploadServlet&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;HTTPServlet&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;AbstractServlet&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;do_POST&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;res&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;filedata&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;query&lt;/span&gt;&lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;filename&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;      &lt;span class="ident"&gt;f&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;open&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;foo.out&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;wb&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;syswrite&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;filedata&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;close&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;      &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Saved file OK&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;mount&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;/upload&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="constant"&gt;FileUploadServlet&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="ident"&gt;trap&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;INT&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;){&lt;/span&gt; &lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;shutdown&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;start&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is the HTML form to test this servlet with&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;form action=&amp;quot;http://localhost:8090/upload&amp;quot; method=&amp;quot;POST&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot;&amp;gt;&lt;br /&gt;File: &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;filename&amp;quot;&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Upload&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-4129906490132161457?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/4129906490132161457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=4129906490132161457' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/4129906490132161457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/4129906490132161457'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2009/01/rubywebrick-file-upload-using.html' title='Ruby/Webrick File upload using multipart/form-data'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-4095161645795582244</id><published>2009-01-21T06:57:00.004-07:00</published><updated>2009-01-21T08:42:55.721-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby mysql dao'/><title type='text'>FireStorm now supports Ruby</title><content type='html'>FireStorm/DAO 4.0.1 includes a Ruby DAO code generator for MySQL (using the mysql-ruby library to interact with the database). To see sample generated Ruby DAO code, take a look at this &lt;a href="http://www.codefutures.com/mysql-ruby"&gt;MySQL-Ruby Tutorial&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The new release is available to download &lt;a href="http://www.codefutures.com/products/firestorm/download/"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-4095161645795582244?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/4095161645795582244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=4095161645795582244' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/4095161645795582244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/4095161645795582244'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2009/01/firestorm-now-supports-ruby.html' title='FireStorm now supports Ruby'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-1412764782414526154</id><published>2009-01-14T11:38:00.004-07:00</published><updated>2009-01-14T12:10:43.258-07:00</updated><title type='text'>Python first impressions</title><content type='html'>Over the past couple of months I have started developing in Python and to a lesser degree so far, Ruby. I have mostly only used strongly typed compiled languages, namely C++ and Java throughout my career and have often resisted doing anything in scripting languages that I felt I could do in Java or C++, mostly because I'm already proficient in those languages and I rarely have too much time for non-essential learning curves.&lt;br /&gt;&lt;br /&gt;However, I am now building some tooling for dbShards, our database sharding, replication, and failover solution, using Python. The main reason for choosing Python over Java is that we wanted a lightweight framework that makes it easy to monitor and control operating system processes on remote servers. Python was recommended to me by a friend (thanks, Paul!) and so far it looks like a pretty good choice, although I'm sure Ruby would also have been a good choice for this project.&lt;br /&gt;&lt;br /&gt;Both Python and Ruby are object oriented to varying degrees but both allow good object oriented design and implementation making it easy for Java developers to pick up the language. The Python syntax has a couple of things that don't feel too natural, such as constructors being called __init__() and the fact that all non-static methods on a class must have a 'self' parameter rather than having a built in 'this' attribute as in Java. Neither of these is really a problem at all and they soon start to feel natural enough. The only real bugbear I have have with the Python language itself is the indentation syntax - Python purely relies on indentation (tabs and spaces) in the code to determine nesting rather than using curly braces or any other form of begin/end syntax. As a result, I find myself constantly switching between text editors and vi to fix indenting issues at the moment. I will have to spend some time researching IDEs for Python (so far I have been using the IntelliJ plugin, the PyDev plugin for Eclipse, and TextMate and none of them seem great at preserving the indents correctly). If anyone has any recommendations for Python tools please let me know.&lt;br /&gt;&lt;br /&gt;Those issues aside, Python is a nice language and easy to learn. Most tasks can be implemented faster than the same tasks using Java, but not to the degree that many report (I have seen many claims of 5-10x productivity gains over Java and these might be true for someone who is not proficient in Java I suppose). The bigger challenge is the Python standard library which is very poorly documented. I spent almost a full day yesterday implementing a web server that supports "multipart/form-data" using the built-in BaseHTTPServer and cgi classes based on the documentation. I think the main issue was that I was using version 3.0 and it appears that this release is perhaps a bit too new to be used for production. When I ported my code back to version 2.5.1 it worked fine.&lt;br /&gt;&lt;br /&gt;Python is undergoing some major changes at the moment and version 3.0 was released just a few weeks ago. There are some pretty fundamental changes between version 2.6.x and 3.0 such as "print" changing from being a statement to being a function, that make it impractical, to say the least, to write code that can work with both versions.&lt;br /&gt;&lt;br /&gt;I have decided to stick with version 2.5.1 for now and port my code at a later date once 3.0 is stable enough (and once binary distributions are available for the platforms we need to support).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-1412764782414526154?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/1412764782414526154/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=1412764782414526154' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/1412764782414526154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/1412764782414526154'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2009/01/python-first-impressions.html' title='Python first impressions'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-3104852869255034256</id><published>2009-01-05T11:26:00.002-07:00</published><updated>2009-01-05T11:39:12.121-07:00</updated><title type='text'>Eclipse "Unable to load default SVN Client"</title><content type='html'>After performing a fresh install of Eclipse Ganymede and Subclipse on Fedora 10, I get the error "Unable to load default SVN Client" when trying to import a project. After installing "JavaHL Adapter", "SVNKit" and "JNA Library" whatever those are it now works. Surely these should be flagged as "required" rather than "optional" or "recommended"?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-3104852869255034256?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/3104852869255034256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=3104852869255034256' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/3104852869255034256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/3104852869255034256'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2009/01/eclipse-unable-to-load-default-svn.html' title='Eclipse &quot;Unable to load default SVN Client&quot;'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-8072057332410555074</id><published>2009-01-05T11:19:00.004-07:00</published><updated>2009-01-05T11:24:27.442-07:00</updated><title type='text'>Fedora 10 network configuration is broken</title><content type='html'>And the new year gets off to a frustrating start ... I installed Fedora 10 on one of my QA machines this weekend and ran into some problems today when I attempted to change the network settings to use static IP. It turns out that the GUI network configuration tool is broken in Fedora 10 and does not save the netmask value (it seems to write the gateway IP address to the netmask field in the configuration file). The workaround for this issue was simply to edit  /etc/sysconfig/network-scripts/ifcfg-eth0 manually and enter the correct netmask value. Unfortunately I wasted half an hour before realising what the problem was. My day can only get better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-8072057332410555074?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/8072057332410555074/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=8072057332410555074' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/8072057332410555074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/8072057332410555074'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2009/01/fedora-10-network-configuration-is.html' title='Fedora 10 network configuration is broken'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-423911846108636328</id><published>2009-01-04T01:00:00.000-07:00</published><updated>2009-01-05T11:08:16.222-07:00</updated><title type='text'>Relocation to Colorado</title><content type='html'>My blog has been rather quiet lately. The main reason for this is that I relocated from England to Colorado in September with my family as a result of some changes at CodeFutures which I will blog about soon. It's an incredibly exciting time both for CodeFutures and for me personally.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-423911846108636328?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/423911846108636328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=423911846108636328' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/423911846108636328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/423911846108636328'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/01/relocation-to-colorado.html' title='Relocation to Colorado'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-50174367541722065</id><published>2008-09-29T07:07:00.009-06:00</published><updated>2008-09-29T07:54:15.639-06:00</updated><title type='text'>MySQL Replication Lag</title><content type='html'>MySQL replication offers a quick and easy solution for having data replicated from a master database to one or more slave databases for failover and/or load balancing of read queries for scalability and is often the first step in a company’s backup and failover strategy.&lt;br /&gt; &lt;br /&gt;MySQL replication is completely asynchronous, meaning that the front-end application (often a web site) does not have to wait for replication to happen on each transaction and this keeps the master database operating efficiently.&lt;br /&gt; &lt;br /&gt;However, having a completely asynchronous replication solution means that the slave database is never 100% up to date. There is an even more serious issue with MySQL replication because it is single-threaded in nature to ensure transactions are applied to the slave database in the same order that they were applied to the master. This means that if the master database is under load with 100 concurrent transactions for a period of time and the slave is only able to process 1 concurrent transaction due to the single-threaded implementation then the slave database will very quickly fall behind the master database and this could mean thousands or tens of thousands of rows that are not replicated and if the master database fails then these transactions could be lost. I'm sure most companies would find this unacceptable.&lt;br /&gt;&lt;br /&gt;I'm curious how developers and DBAs view this issue. It seems unlikely that anyone is entirely comfortable with an unreliable "best effort" replication system for failover although it might be acceptable for scalability if the application is intelligent enough to work around any lag issues optimistically by querying a slave first and then going to the master if the slave is not up to date.&lt;br /&gt;&lt;br /&gt;Google have contributed open source code for &lt;a href="http://code.google.com/p/google-mysql-tools/wiki/SemiSyncReplicationDesign" target="new"&gt;SemiSyncReplication&lt;/a&gt; which provides a partial solution to the problem. Their approach is to have the master sychronously replicate the transaction to the slave mysql instance when the transaction is committed on the master but does not wait for the slave to actually write the transaction to disk, therefore maintaining a sensible balance between performance and reliability.&lt;br /&gt;&lt;br /&gt;How do you handle the issue of MySQL replication lag in your organization? Do you use Google SemiSyncReplication or have you found other products/tools to mitigate against replication lag?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-50174367541722065?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/50174367541722065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=50174367541722065' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/50174367541722065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/50174367541722065'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/09/mysql-replication-lag.html' title='MySQL Replication Lag'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-6811612333694497830</id><published>2008-07-20T08:11:00.006-06:00</published><updated>2008-07-20T09:58:28.462-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spring dao'/><title type='text'>Spring DAO</title><content type='html'>Spring DAO support has been improved in the latest FireStorm 4.0 beta, which is now available for &lt;a href="http://www.codefutures.com/products/firestorm/download/"&gt;download&lt;/a&gt;. Each Spring DAO method is now annotated as @Transactional and the spring configuration file specifies a DataSourceTransactionManager. By default the DAO finder methods now return typed lists e.g. List&amp;lt;Customer&amp;gt; rather than arrays.&lt;br /&gt;&lt;br /&gt;There are some improvements to Spring MVC support as well. FireStorm now generates a single controller per table which extends MultiActionController.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-6811612333694497830?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/6811612333694497830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=6811612333694497830' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/6811612333694497830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/6811612333694497830'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/07/spring-dao.html' title='Spring DAO'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-1245862988113876673</id><published>2008-06-29T05:08:00.012-06:00</published><updated>2008-06-29T05:34:50.568-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java linux'/><title type='text'>The generated script approach to running shell commands from Java</title><content type='html'>Running external process from Java is simple enough using Runtime.exec() but there are some well documented limitations which are covered in detail in an old but still relevant JavaWorld article entitled &lt;a href="http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1" target="new"&gt;When Runtime.exec() won't&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I recently needed to launch a MySQL backup from Java but needed to redirect stdout and stderr to file. Unfortunately, Runtime.exec() can only be used to run an executable file and pass parameters in. It does not support more complex operations such as piping the output of one process into another process or even redirecting stdout or stderr. In other words, Runtime.exec() can’t be used as a linux command line replacement.&lt;br /&gt;&lt;br /&gt;For example, this works correctly:&lt;br /&gt;&lt;pre&gt;&lt;span class="code"&gt;Runtime.getRuntime().exec( “/usr/bin/mysqldump mydb --result-file=mydb.dump” );&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But this will not work:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="code"&gt;Runtime.getRuntime().exec( “/usr/bin/mysqldump mydb --result-file=mydb.dump &gt;stdout.txt 2&gt;stderr.txt” );&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This last code fragment runs without error but the stdout.txt and stderr.txt files are not created.&lt;br /&gt;&lt;br /&gt;The standard solution to this problem is to write Java code to launch two threads, one to read the output stream from the process and one to read the error stream and then write the output from those streams to disk from within Java, but this seems like a heavyweight solution in this instance. There is also a risk of the subprocess hanging if the Java code does not read the output from the process quickly enough, as outlined in the javadocs:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-style: italic;"&gt;“Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.”&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;A simpler solution to allow arbitrary linux command lines to be run from Java is to write the command to a shell script and then execute the shell script. For example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="code"&gt;private static void &lt;/span&gt;&lt;span class="code"&gt;runCommand(String cmd) &lt;/span&gt;&lt;span class="code"&gt;throws &lt;/span&gt;&lt;span class="code"&gt;IOException, InterruptedException {&lt;br /&gt; &lt;br /&gt;        &lt;/span&gt;&lt;span class="comment"&gt;// generate a script file containg the command to run&lt;/span&gt;&lt;span class="code"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span class="code"&gt;final &lt;/span&gt;&lt;span class="code"&gt;File scriptFile = &lt;/span&gt;&lt;span class="code"&gt;new &lt;/span&gt;&lt;span class="code"&gt;File(&lt;/span&gt;&lt;span class="literal"&gt;&amp;quot;/tmp/runcommand.sh&amp;quot;&lt;/span&gt;&lt;span class="code"&gt;);&lt;br /&gt;        PrintWriter w = &lt;/span&gt;&lt;span class="code"&gt;new &lt;/span&gt;&lt;span class="code"&gt;PrintWriter(scriptFile);&lt;br /&gt;        w.println( &lt;/span&gt;&lt;span class="literal"&gt;&amp;quot;#!/bin/sh&amp;quot; &lt;/span&gt;&lt;span class="code"&gt;);&lt;br /&gt;        w.println( cmd  ); &lt;br /&gt;        w.close(); &lt;br /&gt; &lt;br /&gt;        &lt;/span&gt;&lt;span class="comment"&gt;// make the script executable&lt;/span&gt;&lt;span class="code"&gt;&lt;br /&gt;        Process p = Runtime.getRuntime().exec( &lt;/span&gt;&lt;span class="literal"&gt;&amp;quot;chmod +x &amp;quot; &lt;/span&gt;&lt;span class="code"&gt;+ scriptFile.getAbsolutePath() );&lt;br /&gt;        p.waitFor(); &lt;br /&gt; &lt;br /&gt;        &lt;/span&gt;&lt;span class="comment"&gt;// execute the script&lt;/span&gt;&lt;span class="code"&gt;&lt;br /&gt;        p = Runtime.getRuntime().exec( scriptFile.getAbsolutePath() ); &lt;br /&gt;        p.waitFor(); &lt;br /&gt;    }&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Using this approach, I can now simply run:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="code"&gt;runCommand(“/usr/bin/mysqldump mydb --result-file=mydb.dump &gt;stdout.txt 2&gt;stderr.txt”);&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This approach works fine for my requirement, without the overhead of creating additional Java threads. However, this approach is not suitable if the Java application needs to read the output of the process before the process has completed, in which case the standard approach of launching threads to read the output streams should be used.&lt;br /&gt;&lt;br /&gt;The generated script approach is very convenient for enabling general purpose linux command line usage from Java.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-1245862988113876673?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/1245862988113876673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=1245862988113876673' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/1245862988113876673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/1245862988113876673'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/06/generated-script-approach-to-running.html' title='The generated script approach to running shell commands from Java'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-4188291178181130362</id><published>2008-06-18T15:23:00.002-06:00</published><updated>2008-06-18T15:26:33.349-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='internet'/><title type='text'>Skype 4.0 promises high definition full screen video</title><content type='html'>I'm looking forward to getting my hands on &lt;a href="http://news.bbc.co.uk/newsbeat/hi/technology/newsid_7461000/7461018.stm" target="new"&gt;Skype 4.0&lt;/a&gt;. I wonder how well full screen video will really work on standard broadband connections. Sounds a little too good to be true. You can do full screen video with the current Skype version but the picture quality is pretty poor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-4188291178181130362?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/4188291178181130362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=4188291178181130362' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/4188291178181130362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/4188291178181130362'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/06/skype-40-promises-high-definition-full.html' title='Skype 4.0 promises high definition full screen video'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-1606883749214372583</id><published>2008-06-12T02:15:00.001-06:00</published><updated>2008-06-12T02:25:09.274-06:00</updated><title type='text'>Database sharding with Python</title><content type='html'>I just read an interesting post over on &lt;a href="http://highscalability.com" target="new"&gt;highscalability.com&lt;/a&gt;. There is an early stage open source project called &lt;a href="http://highscalability.com/pyshards-aspires-build-sharding-toolkit-python" target="new"&gt;Pyshards&lt;/a&gt; that provides database sharding for Python developers. It's interesting to see sharding toolkits emerge for languages other than Java.&lt;br /&gt;&lt;br /&gt;I've been working extensively with database sharding for around 9 months now and it's an exciting area of technology that offers a very cost-effective way to implement near-linear database scalability using commodity hardware.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-1606883749214372583?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/1606883749214372583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=1606883749214372583' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/1606883749214372583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/1606883749214372583'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/06/database-sharding-with-python.html' title='Database sharding with Python'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-2631772507385290520</id><published>2008-06-04T04:39:00.003-06:00</published><updated>2008-06-04T05:53:30.218-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Is Maven the right choice for your project?</title><content type='html'>Over the past 6 months or so I have been working with some projects that have a Maven2 build system and other projects that use plain Ant build systems. I love the concepts behind Maven and see tremendous value in standardizing the build process across projects as well as having a better way of managing dependencies on third party jars without storing them in each project's source repository.&lt;br /&gt;&lt;br /&gt;However, there are some pitfalls to be aware of before adopting Maven which may or may not be issues depending on your requirements.&lt;br /&gt;&lt;br /&gt;First of all, adopting Maven will typically require a Maven server (repository) to be set up and maintained. For some smaller development departments this creates an extra IT support burden that can be avoided with an Ant build system.&lt;br /&gt;&lt;br /&gt;Another potential issue is that third party projects might not have good support for Maven. For instance, another Apache project, Axis2, recently released version 1.4 but there is an open support ticket &lt;a href="http://issues.apache.org/jira/browse/AXIS2-3069"&gt;AXIS2-3069&lt;/a&gt; regarding the Maven2 java2wsdl plugin which does not seem to be in a working state yet. The ticket has not been updated since 2007. Sure, the problem can be worked around by calling Ant from within the Maven2 project, but that's adding another layer of complexity compared to a standard Ant project.&lt;br /&gt;&lt;br /&gt;Another issue that I have hit is that Maven2 has poor error reporting when it is unable to resolve a dependency. I eventually tracked my issue down to a java keystore / server certificate error but Maven didn't provide any hints that this was the problem, even with debug flags set.&lt;br /&gt;&lt;br /&gt;Overall, I'm still a fan of Maven2 and I think the combination of Maven and Ant is extremely powerful but in my recent experience it does add extra cost to the development process.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-2631772507385290520?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/2631772507385290520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=2631772507385290520' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/2631772507385290520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/2631772507385290520'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/06/is-maven-right-choice-for-your-project.html' title='Is Maven the right choice for your project?'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-5830375383374887864</id><published>2008-06-02T04:04:00.002-06:00</published><updated>2008-06-02T04:09:57.034-06:00</updated><title type='text'>High Performance MySQL</title><content type='html'>I spent some time this morning reading High Performance MySQL by Jeremy Zawodny &amp;amp; Derek Balling (O'Reilly). I've had this book on my shelf for a year or two now and have found it an excellent reference whenever architecting solutions that use MySQL for persistence. The sections on server performance tuning, replication, and backup and recovery are especially useful. This book really is a must read for any developers, DBAs or sysadmins working with MySQL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-5830375383374887864?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/5830375383374887864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=5830375383374887864' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/5830375383374887864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/5830375383374887864'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/06/high-performance-mysql.html' title='High Performance MySQL'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-4820581550467943203</id><published>2008-05-13T03:52:00.000-06:00</published><updated>2008-05-19T03:53:09.408-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dao'/><title type='text'>FireStorm/DAO on Mac OS X</title><content type='html'>The latest &lt;a href="http://www.codefutures.com/firestormdao/download/"&gt;FireStorm&lt;/a&gt;/&lt;a href="http://www.codefutures.com/firestormdao/download/"&gt;DAO&lt;/a&gt; 4.0 beta download for Mac OS X now uses a single menu bar at the top of the screen in true Mac style and the toolbar buttons no longer have ugly borders. Sorry we didn't do this sooner but we just started using Apple hardware.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-4820581550467943203?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/4820581550467943203/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=4820581550467943203' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/4820581550467943203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/4820581550467943203'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/05/firestormdao-on-mac-os-x.html' title='FireStorm/DAO on Mac OS X'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-2285077143593976514</id><published>2008-03-27T02:38:00.003-06:00</published><updated>2008-03-27T03:08:07.508-06:00</updated><title type='text'>MacBook Pro - Day 1</title><content type='html'>As I mentioned a few &lt;a href="http://www.codesuccess.com/blog/2008/03/sony-vaio-or-macbook-pro.html"&gt;days ago&lt;/a&gt;, I was in the market for a new laptop and was mostly looking at Windows machines until I realised that there was no good reason why I shouldn't buy a MacBook Pro instead. I decided to take the plunge and I ordered the 15" model, which arrived yesterday.&lt;br /&gt;&lt;br /&gt;I've been developing on Intel machines since 1989, starting out with DOS and then working my way through Windows 3.1, 2000, NT, XP and Vista so to switch to a different OS is a bit of a leap of faith. From time to time I had considered installing linux on a laptop but frankly it is too time consuming to get things working and I have precious little time as it is. &lt;br /&gt;&lt;br /&gt;The main attraction of moving to Mac OS X is that it is linux based and I can now use many of the same commands on my development machine as I use on the environments I deploy to.  I also like the fact that the hardware and software have been produced by the same company and should therefore provide a stable and optimized platform.&lt;br /&gt;&lt;br /&gt;The install experience was easily the best I have experienced on any computer. I was able to check out a couple of Java project from subversion and get them building with minimal fuss. The MacBook Pro built one of the projects about 25% faster than my Windows Vista desktop machine which on paper has a better spec, so Mac OS X does appear to be more efficient.&lt;br /&gt;&lt;br /&gt;I love the fact that there is a DVI port built in and this gives a crisp image when connected to my 24" Samsung monitor. The MagSafe power adaptor was a bit of an experience. I'm not ashamed to admit that I had to search on Google to find out how I was supposed to disconnect it.&lt;br /&gt;&lt;br /&gt;I've installed vmware fusion (an impressive piece of software) and I have a Windows XP and a Fedora 8 virtual machine, primarily for running unit tests on those platforms.&lt;br /&gt;&lt;br /&gt;It will take me a couple of days to get used to the keyboard but as this will be my only machine on a trip to Colorado next week I'll be forced to get up to speed quickly.&lt;br /&gt;&lt;br /&gt;I'm extremely impressed so far!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-2285077143593976514?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/2285077143593976514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=2285077143593976514' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/2285077143593976514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/2285077143593976514'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/03/macbook-pro-day-1.html' title='MacBook Pro - Day 1'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-4332128795324565253</id><published>2008-03-20T03:21:00.003-06:00</published><updated>2008-03-20T11:34:03.772-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>Sony Vaio or MacBook Pro?</title><content type='html'>I have the opportunity to buy a new laptop and I have a budget of £1,500 (plus VAT). My main requirements are decent processing power (2.4GHz Core 2 Duo + 4GB RAM) and a good quality high resolution display (ideally WUXGA 1920x1200) and a keyboard that it suited to development work (so functions like 'home' and 'end' can't involve complex multi-key actions involving several keys at the same time).&lt;br /&gt;&lt;br /&gt;My initial shortlist included the Lenovo Thinkpad T61p, the Dell Precision M6300, and the Sony Vaio AR61ZU. I was pretty much settled on the Sony although I was concerned that this might be a bit larger than I really wanted due to the 17" display. I've now realised that the MacBook Pro is also a contender so I now have to choose between that and the Sony Vaio (which is pretty much the Apple of the PC world).&lt;br /&gt;&lt;br /&gt;Apart the basics of email and web, I'll be using the machine for Java development work 90% of the time and the tools I use are available on all platforms. The only Microsoft specific tools I need to use are Word and Excel. They are both available on the Mac, at a price. I guess there's always the option of using OpenOffice but I don't know how well that really works, especially with Office 2007 files.&lt;br /&gt;&lt;br /&gt;The MacBook Pro is probably the better choice for development work given that the OS is linux based (most of the development work I do is targeted at unix or linux production environments).&lt;br /&gt;&lt;br /&gt;It's a tough call. Suggestions anyone?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-4332128795324565253?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/4332128795324565253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=4332128795324565253' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/4332128795324565253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/4332128795324565253'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/03/sony-vaio-or-macbook-pro.html' title='Sony Vaio or MacBook Pro?'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-7406673496320095883</id><published>2008-01-27T03:22:00.000-07:00</published><updated>2008-01-27T03:36:20.779-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='scalability'/><title type='text'>More on Hibernate</title><content type='html'>I got some flack a few months back when I posted an article about &lt;a target="new" href="http://www.codesuccess.com/blog/2007/10/hibernate-conclusions.html"&gt;poor scalability when using Hibernate&lt;/a&gt; for a proof of concept I was working on at the time. For that particular project it seems that Hibernate probably wasn't the best fit. However, I've now had the opportunity to use Hibernate on another project and my experience has been much better this time. First of all, the productivity benefits of using Hibernate rather than writing Spring JDBC code are quite impressive. I was able to get a prototype web application up and running in just a couple of hours with Hibernate because I really did only have to focus on the business logic rather than writing low level code. Scalability isn't at all critical for this application since it will not have a huge number of users but I ran some tests anyway to compare one of the transactions with a hand-coded JDBC equivalent. Here are the results:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.codesuccess.com/img/blog/jdbc_hibernate.jpg" border="0" alt="JDBC versus Hibernate"&gt;&lt;br /&gt;&lt;br /&gt;It's true - Hibernate does add some overhead to the transaction but it's a price I'm happy to pay for the time saved in development. I expect there are other transactions in the system where Hibernate will be faster than JDBC due to caching.&lt;br /&gt;&lt;br /&gt;I still stand by my &lt;a target="new" href="http://www.codesuccess.com/blog/2007/10/hibernate-conclusions.html"&gt;previous conclusion&lt;/a&gt;, which is that it is always worth benchmarking products/technologies against real use cases to make sure they are suitable choices. One size does not fit all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-7406673496320095883?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/7406673496320095883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=7406673496320095883' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/7406673496320095883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/7406673496320095883'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/01/more-on-hibernate.html' title='More on Hibernate'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-1659767344103133229</id><published>2008-01-16T16:27:00.000-07:00</published><updated>2008-01-16T16:33:54.366-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='industry'/><title type='text'>Sun to buy MySQL for $1 billion</title><content type='html'>I just heard that Sun are acquiring MySQL for around $1 billion. The press release is &lt;a target="new"  href="http://www.mysql.com/news-and-events/sun-to-acquire-mysql.html"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-1659767344103133229?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/1659767344103133229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=1659767344103133229' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/1659767344103133229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/1659767344103133229'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/01/sun-to-buy-mysql-for-1-billion.html' title='Sun to buy MySQL for $1 billion'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-3421966794706016665</id><published>2008-01-04T06:35:00.000-07:00</published><updated>2008-01-04T07:21:17.993-07:00</updated><title type='text'>Sending extended character sets with OpenSMPP</title><content type='html'>There's astonishingly little documentation on the web about sending international characters in SMS messages using &lt;a href="http://smstools.sourceforge.net/" target="new"&gt;OpenSMPP&lt;/a&gt; (which is based on the &lt;a href="http://opensmpp.logica.com/" target="new"&gt;Logica SMPP API&lt;/a&gt;). After a bit of research and some experimentation I've established that the following steps are required:&lt;br /&gt;&lt;br /&gt;1. data_coding must be set to 0x08 (instructs the SMSC to use UCS-2 encoding - see section 5.2.19 in the &lt;a href="http://www.hslsms.com/documents/SMPPV3.4.pdf" target="new"&gt;SMPP protocol specification &lt;/a&gt; for other data codings)&lt;br /&gt;2. When setting the message content, it must be encoded with UTF16&lt;br /&gt;&lt;br /&gt;Here's some partial source code to demonstrate the point:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; SubmitSM request = new SubmitSM();&lt;br /&gt; request.setDataCoding( 0x08 ); // UCS-2 &lt;br /&gt; request.setShortMessage( messageText, Data.ENC_UTF16 );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It's worth noting that the maximum message length is reduced from 160 characters to 70 characters when using UCS-2.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-3421966794706016665?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/3421966794706016665/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=3421966794706016665' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/3421966794706016665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/3421966794706016665'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2008/01/sending-extended-character-sets-with.html' title='Sending extended character sets with OpenSMPP'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1017709164693452092.post-8583415818075674541</id><published>2007-12-31T02:36:00.001-07:00</published><updated>2007-12-31T04:43:41.462-07:00</updated><title type='text'>MySQL SemiSyncReplication</title><content type='html'>One of the projects I'm involved in at the moment has required some research into strategies for clustering MySQL for HA. One of the interesting ideas that we came across is some code from Google that adds semi-synchronous replication to MySQL's built in replication feature. Standard MySQL replication is asynchronous, meaning that transactions are committed on the master database and at some point after that (could be milliseconds, could be minutes or longer) the slave databases will receive the transactions and replicate them. This is great for performance but if the master database dies then transactions are likely to be lost due to the lag between the master and slaves. One of Google's contribution is to make the master database wait until the transaction has been received by one or more slave databases before acknowledging to the client the transaction has been committed. This doesn't 100% guarantee that transactions won't be lost (the slave could die before the transaction is actually written to disk) but it dramatically reduces the likelihood of transactions being lost. Of course, the price to pay is that writes to the master will be slower but thats pretty much always the trade-off between performance and reliability.&lt;br /&gt;&lt;br /&gt;Here's a link to the Google MySQL Tools project.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/google-mysql-tools/w/list"&gt;http://code.google.com/p/google-mysql-tools/w/list&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1017709164693452092-8583415818075674541?l=www.codefutures.com%2Fweblog%2Fandygrove'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/8583415818075674541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1017709164693452092&amp;postID=8583415818075674541' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/8583415818075674541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1017709164693452092/posts/default/8583415818075674541'/><link rel='alternate' type='text/html' href='http://www.codefutures.com/weblog/andygrove/2007/12/mysql-semisyncreplication.html' title='MySQL SemiSyncReplication'/><author><name>Andy Grove</name><uri>http://www.blogger.com/profile/13991619444627251911</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='18018845070304692187'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>