<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6543848899761399219</id><updated>2011-09-28T23:24:49.741+02:00</updated><category term='project voldemort'/><category term='1.1'/><category term='infinispan'/><category term='hibernate'/><category term='drizzle'/><category term='cassandra'/><category term='0.8'/><category term='rabbitreplication'/><category term='scala'/><category term='jdbc'/><category term='guice'/><category term='java'/><category term='javaone'/><category term='tungsten'/><category term='librabbitmq'/><category term='memcached'/><category term='rabbitmq'/><category term='maven'/><category term='blob streaming'/><category term='drizzle-jdbc'/><category term='websockets'/><category term='pbms'/><category term='replication'/><title type='text'>Developian</title><subtitle type='html'>Development blog, you will find posts about drizzle-jdbc and rabbitreplication here.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://developian.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>39</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-515167015157005997</id><published>2011-08-10T09:36:00.000+02:00</published><updated>2011-08-10T09:36:24.382+02:00</updated><title type='text'>ZeroMQ support in Drizzle</title><content type='html'>My little &lt;a href="http://www.zeromq.org/"&gt;zeromq&lt;/a&gt; plugin just hit drizzle trunk, it is simply a replication plugin that publishes a multi-frame message on a ZeroMQ endpoint. The first frame contains the name of the schema the transaction was executed against and the second frame is the actual protobuf-serialized transaction.&lt;h3&gt;Getting started&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;Install zeromq&lt;/li&gt;&lt;li&gt;Build &amp; install Drizzle (it will pick up the zeromq libs automatically)&lt;/li&gt;&lt;li&gt;Start drizzled with --plugin-add=zeromq (this binds a zeromq socket on tcp://*:9999 - change this by setting --zeromq.endpoint=[whatever])&lt;/li&gt;&lt;li&gt;Profit&lt;/li&gt;&lt;/ol&gt;Try it out by running this small python script:&lt;code&gt;&lt;pre&gt;&lt;br /&gt;import zmq&lt;br /&gt;&lt;br /&gt;ctx = zmq.Context()&lt;br /&gt;s = ctx.socket(zmq.SUB)&lt;br /&gt;s.setsockopt(zmq.SUBSCRIBE, '')&lt;br /&gt;s.connect('tcp://localhost:9999')&lt;br /&gt;i = 0&lt;br /&gt;while True:&lt;br /&gt;    i = i+1&lt;br /&gt;    print s.recv_multipart()&lt;br /&gt;    print i&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;You should see output on the form ['the_schema', *blob*].&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-515167015157005997?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/515167015157005997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=515167015157005997' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/515167015157005997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/515167015157005997'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2011/08/zeromq-support-in-drizzle.html' title='ZeroMQ support in Drizzle'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-3695794560349191698</id><published>2011-04-24T08:58:00.000+02:00</published><updated>2011-04-24T08:58:09.211+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='1.1'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><title type='text'>Drizzle JDBC 1.1 - SSL support and multi queries</title><content type='html'>Just pushed up Drizzle JDBC 1.1 with 2 quite big new features:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;SSL support - add &lt;b&gt;?useSSL=true&lt;/b&gt; in the connection string (and do the usual ssl-in-java magic to make it work. Check the MySQL documentation for more information, it is set up exactly the same way here)&lt;/li&gt;&lt;li&gt;Multi queries - add &lt;b&gt;?allowMultiQueries=true&lt;/b&gt; to your connection string to be able to send several queries in one round trip to the server.&lt;/li&gt;&lt;/ul&gt;Note that these features are only supported when using the driver against a MySQL server - Drizzle does not have these features (yet).&lt;br /&gt;&lt;br /&gt;Download it from the &lt;a href="http://repo2.maven.org/maven2/org/drizzle/jdbc/drizzle-jdbc/"&gt;central maven repo&lt;/a&gt; (should be synced within an hour or so)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-3695794560349191698?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/3695794560349191698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=3695794560349191698' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/3695794560349191698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/3695794560349191698'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2011/04/drizzle-jdbc-11-ssl-support-and-multi.html' title='Drizzle JDBC 1.1 - SSL support and multi queries'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-6350987908239429098</id><published>2011-04-11T09:12:00.000+02:00</published><updated>2011-04-11T09:12:13.794+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><title type='text'>Drizzle JDBC 1.0</title><content type='html'>Finally got around to making a 1.0-release of Drizzle JDBC, after a while of not getting any bug reports (not at all claiming that it is bug free, but it is stable enough for several companies to use it in production).&lt;br /&gt;&lt;br /&gt;Far those new to Drizzle JDBC, it is a BSD-licensed JDBC driver for &lt;a href="http://www.drizzle.org"&gt;Drizzle&lt;/a&gt; and &lt;a href="http://www.mysql.com"&gt;MySQL&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Changelog&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;DatabaseMetaData fix - return column_type instead of data_type, contains more information (by Stephane Giron)&lt;/li&gt;&lt;li&gt;Detect if a blob is actually a CLOB by checking charset number (by Christian Peter)&lt;/li&gt;&lt;li&gt;Connect with UTF-8 charset default (bug reported by Marc Isambart)&lt;/li&gt;&lt;li&gt;Support for connection timeouts (by Marc Isambart) - add ?connectTimeout=X to have an X second connection timeout.&lt;/li&gt;&lt;li&gt;Properly support TIME and BOOLEAN datatypes in Drizzle&lt;/li&gt;&lt;li&gt;Move query timeout thread to the Connection class instead of having it in the statement class (duh) - now one extra thread per Connection instead of one per Statement. Is safe since only one statement can run in one connection at a time.&lt;/li&gt;&lt;li&gt;Generally shape up UTF8 handling throughout the driver (by Marc Isambart and me).&lt;/li&gt;&lt;li&gt;Update copyright headers, now includes the standard Simplified BSD license header.&lt;/li&gt;&lt;li&gt;Add an &lt;a href="http://bazaar.launchpad.net/~krummas/drizzle-jdbc/trunk/view/head:/AUTHORS"&gt;AUTHORS&lt;/a&gt; file&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Whats next?&lt;/h3&gt;So, the general plan for the future is:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Make the driver more modular - it should be possible for users to change the behavior of almost every aspect of the driver&lt;/li&gt;&lt;li&gt;Support the optional &lt;a href="http://download.oracle.com/javase/6/docs/api/javax/sql/package-summary.html"&gt;javax.sql&lt;/a&gt; packages - XA handling etc. This will be built as a separate maven-published jar to keep size of the basic driver small&lt;/li&gt;&lt;li&gt;Support the SQL escape syntax (never used it, but i guess it should be there...)&lt;br /&gt;&lt;li&gt;...&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;If any of the things above are more important for anyone, please let &lt;a href="mailto:krummas@gmail.com"&gt;me&lt;/a&gt; know so that i know where to begin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-6350987908239429098?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/6350987908239429098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=6350987908239429098' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/6350987908239429098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/6350987908239429098'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2011/04/drizzle-jdbc-10.html' title='Drizzle JDBC 1.0'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-5825744296215803679</id><published>2011-04-07T12:03:00.000+02:00</published><updated>2011-04-07T12:03:37.427+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rabbitmq'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='rabbitreplication'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><title type='text'>Visualizing data in real time using drizzle and rabbitmq, DEMO!</title><content type='html'>A couple of weeks ago, when Mozilla released firefox 4, i watched &lt;a href="http://glow.mozilla.org"&gt;glow.mozilla.org&lt;/a&gt; - a site made to visualize the firefox downloads in real time. I figured this could be quite a neat use case for my old drizzle to web socket replicator.&lt;br /&gt;&lt;br /&gt;So, the compontents involved:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.drizzle.org"&gt;Drizzle&lt;/a&gt; with the rabbitmq plugin, see &lt;a href="http://developian.blogspot.com/2011/03/publish-transactions-to-rabbitmq-in.html"&gt;this blog post&lt;/a&gt; for more information on how to get it up and running.&lt;/li&gt;&lt;li&gt;&lt;a href="http://launchpad.net/drizzle-jdbc"&gt;Drizzle-JDBC&lt;/a&gt; to generate the data in the database&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.rabbitreplication.org"&gt;RabbitReplication&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.rabbitmq.org"&gt;RabbitMQ&lt;/a&gt; to transport the transactions from drizzle to the applier&lt;/li&gt;&lt;li&gt;Your browser, both &lt;a href="http://www.google.com/chrome"&gt;Chrome&lt;/a&gt; and &lt;a href="http://www.getfirefox.net"&gt;Firefox&lt;/a&gt; support web sockets, but for firefox you need to &lt;a href="http://techdows.com/2010/12/turn-on-websockets-in-firefox-4.html"&gt;enable them first&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The basic flow is this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;10 inserts per second are executed in the drizzle database using drizzle-jdbc, these inserts contain a random IP address&lt;/li&gt;&lt;li&gt;Drizzle does its magic and packages up each insert as a google protobuf transaction message&lt;/li&gt;&lt;li&gt;The rabbitmq plugin picks up the message and publishes it to a RabbitMQ server&lt;/li&gt;&lt;li&gt;RabbitReplication consumes the message from RabbitMQ and maps it onto an &lt;a href="http://bazaar.launchpad.net/~krummas/rabbitreplication/trunk/view/head:/src/org/drizzle/managedclasses/ExampleRepl.java"&gt;annotated java object&lt;/a&gt;. This gives alot of flexibility to the rabbitreplication user since you can manipulate the information any way you want, in this example i extract a longitude and latitude value from the IP address using &lt;a href="http://www.maxmind.com/"&gt;MaxMind GeoLite City&lt;/a&gt;. Have a look at row the "setSomething()" method in the ExampleRepl.java file. This file is something a rabbitreplication end user would implement and provide&lt;/li&gt;&lt;li&gt;The java object is serialized to json&lt;/li&gt;&lt;li&gt;The json string is published to all connected clients&lt;/li&gt;&lt;li&gt;A javascript on the page takes the lat/lng-values and maps these onto a google map&lt;/li&gt;&lt;li&gt;The same javascript appends some of the raw data to a table&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;So, I'm hoping the little demo i'm linking below shows some of the extreme flexibility of the Drizzle replication. This, for me, is the unique selling point for Drizzle. Also, if anyone has an actual production use case for this, i'd be extremely happy to help implement it!&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;h1&gt;&lt;a href="http://demo.rabbitreplication.org" target="_blank"&gt;http://demo.rabbitreplication.org&lt;/a&gt;&lt;/h1&gt;&lt;br&gt;(Thanks to &lt;a href="http://www.rackspace.com"&gt;Rackspace&lt;/a&gt; for hosting!)&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-OPZlFbdYh5k/TZ2Ld-itO2I/AAAAAAAAAUY/OJ6olXdjMMs/s1600/rabbitrepl-websockets.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="278" src="http://4.bp.blogspot.com/-OPZlFbdYh5k/TZ2Ld-itO2I/AAAAAAAAAUY/OJ6olXdjMMs/s400/rabbitrepl-websockets.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-5825744296215803679?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/5825744296215803679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=5825744296215803679' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/5825744296215803679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/5825744296215803679'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2011/04/visualizing-data-in-real-time-using.html' title='Visualizing data in real time using drizzle and rabbitmq, DEMO!'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-OPZlFbdYh5k/TZ2Ld-itO2I/AAAAAAAAAUY/OJ6olXdjMMs/s72-c/rabbitrepl-websockets.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-4740297289563818975</id><published>2011-03-28T21:11:00.000+02:00</published><updated>2011-03-28T21:11:33.261+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rabbitmq'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='rabbitreplication'/><title type='text'>Publish transactions to RabbitMQ in drizzled7</title><content type='html'>Since &lt;a href="http://drizzle.org"&gt;Drizzle&lt;/a&gt; went GA a couple of weeks ago, i figured i should update &lt;a href="http://www.rabbitreplication.org"&gt;rabbitreplication&lt;/a&gt; to support it, quite a few changes have been done to the structure of the protobuf messages etc. First hurdle was to get drizzle to actually publish messages to rabbitmq, so here is a step-by-step tutorial to get started with that.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Install a recent version of &lt;a href="http://rabbitmq.org"&gt;rabbitmq&lt;/a&gt; &lt;/li&gt;&lt;li&gt;Get the latest version of librabbitmq:&lt;br /&gt;&lt;pre&gt;$ hg clone http://hg.rabbitmq.com/rabbitmq-codegen/&lt;br /&gt;$ hg clone http://hg.rabbitmq.com/rabbitmq-c/&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Build it (in the rabbitmq-c directory):&lt;br /&gt;&lt;pre&gt;$ autoreconf -f -i&lt;br /&gt;$ ./configure&lt;br /&gt;$ make&lt;br /&gt;$ make install&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Install Drizzle, follow these instructions:&lt;br /&gt;&lt;a href="http://docs.drizzle.org/#compiling-and-installing"&gt;http://docs.drizzle.org/#compiling-and-installing&lt;/a&gt;. (During ./configure you should see that librabbitmq is found and that the plugin is getting built)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Start Drizzle like this:&lt;br /&gt;&lt;pre&gt;$ sbin/drizzled7 --plugin-add rabbitmq,default-replicator --rabbitmq.use-replicator default&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;To verify that it works, you can run a rabbitmq consumer from rabbitmq-c/examples, like this:&lt;br /&gt;&lt;pre&gt;./amqp_listen localhost 5672 ReplicationExchange ReplicationRoutingKey&lt;/pre&gt;Then execute an insert (or something, just not a select :) ) on your drizzle server, and you should see something like this in your console:&lt;br /&gt;&lt;pre&gt;Result 0&lt;br /&gt;Frame type 1, channel 1&lt;br /&gt;Method AMQP_BASIC_DELIVER_METHOD&lt;br /&gt;Delivery 1, exchange ReplicationExchange routingkey ReplicationRoutingKey&lt;br /&gt;----&lt;br /&gt;00000000: 0A 17 08 01 10 87 36 18 : F0 FA D9 99 FA F1 A7 02  ......6.........&lt;br /&gt;00000010: 20 99 81 DA 99 FA F1 A7 : 02 12 40 08 01 10 F2 FA   .........@.....&lt;br /&gt;00000020: D9 99 FA F1 A7 02 18 FC : FA D9 99 FA F1 A7 02 2A  ...............*&lt;br /&gt;00000030: 17 0A 06 0A 01 62 12 01 : 61 12 06 08 04 12 02 69  .....b..a......i&lt;br /&gt;00000040: 64 12 05 08 01 12 01 74 : 32 11 08 01 10 01 1A 0B  d......t2.......&lt;br /&gt;00000050: 0A 01 32 0A 02 61 61 10 : 00 10 00 20 01 28 01     ..2..aa.... .(.&lt;br /&gt;0000005F:&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;In a couple of days I'll make a new release of rabbitreplication that supports the latest version of drizzle, stay tuned for that! I'll also update the drizzle rabbitmq plugin so that it is actually usable (support reconnect etc)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-4740297289563818975?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/4740297289563818975/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=4740297289563818975' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4740297289563818975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4740297289563818975'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2011/03/publish-transactions-to-rabbitmq-in.html' title='Publish transactions to RabbitMQ in drizzled7'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-4618851473070836437</id><published>2011-02-14T19:58:00.000+01:00</published><updated>2011-02-14T19:58:55.808+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><category scheme='http://www.blogger.com/atom/ns#' term='0.8'/><title type='text'>Drizzle JDBC 0.8</title><content type='html'>Just pushed up Drizzle-JDBC 0.8 to the central maven repository, list of changes is below. To use it, update your poms to include this:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt;   &amp;lt;groupId&amp;gt;org.drizzle.jdbc&amp;lt;/groupId&amp;gt;&lt;br /&gt;   &amp;lt;artifactId&amp;gt;drizzle-jdbc&amp;lt;/artifactId&amp;gt;&lt;br /&gt;   &amp;lt;version&amp;gt;0.8&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Or simply &lt;a href="http://repo2.maven.org/maven2/org/drizzle/jdbc/drizzle-jdbc/0.8/drizzle-jdbc-0.8.jar"&gt;download&lt;/a&gt; the jar file and add it to the classpath. Further instructions on how to us it is available on the &lt;a href="http://wiki.drizzle.org/JDBC"&gt;Drizzle JDBC Wiki&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Drizzle JDBC is a BSD Licensed JDBC driver for &lt;a href="http://www.mysql.com"&gt;MySQL&lt;/a&gt; and &lt;a href="http://drizzle.org"&gt;Drizzle&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Changlog for 0.8&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Allow queries bigger than 16M (Stephane Giron)&lt;/li&gt;&lt;li&gt;Allow prepared statements with large parameters&lt;/li&gt;&lt;li&gt;Allow reading back big result sets&lt;/li&gt;&lt;li&gt;Implement cancel() on statements&lt;/li&gt;&lt;li&gt;Implement query timeouts&lt;/li&gt;&lt;li&gt;Java 5 support (Christian Peter)&lt;/li&gt;&lt;li&gt;Add option to create database if it does not exist (Stephan Giron) - add ?createDB=true to the connection string&lt;/li&gt;&lt;li&gt;Fixes to database metadata queries after drizzle got its data dictionary&lt;/li&gt;&lt;li&gt;Better UTF8 support and BLOB/CLOB fixes (Christian Peter)&lt;/li&gt;&lt;li&gt;Support for MySQL old passwords (Stephane Giron)&lt;/li&gt;&lt;li&gt;LOAD DATA LOCAL INFILE support (Stephane Giron)&lt;/li&gt;&lt;li&gt;Properly close socket (Gilles Rayrat)&lt;/li&gt;&lt;li&gt;Support BigDecimal in setObject&lt;/li&gt;&lt;li&gt;Move maven repositories to the Sonatype OSS repositories&lt;/li&gt;&lt;li&gt;Initial blob streaming (PBMS) support (http://developian.blogspot.com/2010/08/blob-streaming-pbms-support-in-drizzle.html)&lt;/li&gt;&lt;/ul&gt;&lt;br/&gt;&lt;br /&gt;Report any issues/feature requests to me, &lt;a href="mailto:krummas@gmail.com"&gt;krummas@gmail.com&lt;/a&gt; or on &lt;a href="http://launchpad.net/drizzle-jdbc"&gt;http://launchpad.net/drizzle-jdbc&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-4618851473070836437?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/4618851473070836437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=4618851473070836437' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4618851473070836437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4618851473070836437'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2011/02/drizzle-jdbc-08.html' title='Drizzle JDBC 0.8'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-1457342459146387782</id><published>2010-08-11T21:18:00.000+02:00</published><updated>2010-08-11T21:18:29.357+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='blob streaming'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><category scheme='http://www.blogger.com/atom/ns#' term='pbms'/><title type='text'>Blob Streaming (PBMS) support in drizzle jdbc</title><content type='html'>I just pushed up initial support for &lt;a href="http://www.blobstreaming.com"&gt;PBMS&lt;/a&gt;, blob streaming for drizzle jdbc. It is not yet a complete solution for blob streaming, but you can use setBinaryStream and getBinaryStream to stream data to/from Drizzle and MySQL.&lt;br /&gt;&lt;br /&gt;To use it, grab a snapshot from &lt;a href="http://marcus.no-ip.biz/hudson/job/drizzle-jdbc-freestyle/"&gt;hudson&lt;/a&gt; (the reason the tests fail is that i have not had time to rewrite INFORMATION_SCHEMA queries to support the new I_S in Drizzle). Then follow this example to get started, important stuff is in &lt;b&gt;bold&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;Connection connection = &lt;br /&gt;    DriverManager.getConnection(&lt;br /&gt;           "jdbc:drizzle://localhost:3307/test_units_jdbc?&lt;b&gt;enableBlobStreaming=true&lt;/b&gt;");&lt;br /&gt;// inserting a blob:&lt;br /&gt;Statement stmt = connection.createStatement();&lt;br /&gt;stmt.execute("create table bstreaming1 (id int not null primary key auto_increment, test &lt;b&gt;longblob&lt;/b&gt;)");&lt;br /&gt;PreparedStatement ps = connection.prepareStatement("insert into bstreaming1 values (null, ?)");&lt;br /&gt;// fake an inputstream with data:&lt;br /&gt;ByteArrayInputStream bais = new ByteArrayInputStream("HEJHEJHEJ".getBytes());&lt;br /&gt;&lt;b&gt;ps.setBinaryStream(1, bais);&lt;/b&gt;&lt;br /&gt;ps.executeUpdate();&lt;br /&gt;        &lt;br /&gt;stmt = connection.createStatement();&lt;br /&gt;ResultSet rs = stmt.executeQuery("select * from bstreaming1");&lt;br /&gt;assertEquals(rs.next(), true);&lt;br /&gt;byte[] b = new byte[100];&lt;br /&gt;int l = &lt;b&gt;rs.getBinaryStream("test")&lt;/b&gt;.read(b);&lt;br /&gt;assertEquals("HEJHEJHEJ",new String(b,0,l));&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;To get PBMS support in drizzle you need to have a fairly recent build, and start the daemon with --plugin_add=pbms. InnoDB tables are streaming enabled, which means that any LONGBLOB column will be streamed. &lt;br /&gt;&lt;br /&gt;Note that in the current version you will get the blob reference and not a String representation of the blob if you do a getString on the column for example, this will change when I get time to do it.&lt;br /&gt;&lt;br /&gt;I have not yet tested against MySQL, if you have a PBMS enabled MySQL server, please let me know if it works!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-1457342459146387782?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/1457342459146387782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=1457342459146387782' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/1457342459146387782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/1457342459146387782'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2010/08/blob-streaming-pbms-support-in-drizzle.html' title='Blob Streaming (PBMS) support in drizzle jdbc'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-1650085843158422452</id><published>2010-07-05T20:00:00.002+02:00</published><updated>2010-10-07T12:04:11.852+02:00</updated><title type='text'>Help me test my BSD licensed JDBC driver for Drizzle and MySQL</title><content type='html'>I'm developing &lt;a href="http://launchpad.net/drizzle-jdbc"&gt;Drizzle-JDBC&lt;/a&gt; which is a BSD licensed JDBC driver for both &lt;a href="http://www.mysql.com"&gt;MySQL&lt;/a&gt; and &lt;a href="http://drizzle.org"&gt;Drizzle&lt;/a&gt;. The goal is to build a maintainable, "light weight" JDBC driver with a permissive license (it is hard to be truly light weight when implementing the massive JDBC interfaces).&lt;br /&gt;&lt;br /&gt;Now what I really need is beta testers. I don't expect anyone to use it in production, but it would be great if you could try it with any existing application by just placing the .jar on the class path, changing the connection string, and running your test suites/load tests etc. Report any issues to me at &lt;a href="http://bugs.launchpad.net/drizzle-jdbc"&gt;launchpad&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Also, I need some inspiration, are there any features you have wanted to see in a JDBC driver? Cloud aware (if anyone wants this, please define it for me :) )? Plug-in system for query optimization etc?&lt;br /&gt;&lt;h3&gt;How to help:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://repo1.maven.org/maven2/org/drizzle/jdbc/drizzle-jdbc/0.7/drizzle-jdbc-0.7.jar"&gt;Download&lt;/a&gt; Drizzle-JDBC 0.7 and place it on your classpath, or, if you use maven, add this dependency to your pom.xml:&lt;br /&gt;&lt;pre&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt;  &amp;lt;groupId&amp;gt;org.drizzle.jdbc&amp;lt;/groupId&amp;gt;&lt;br /&gt;  &amp;lt;artifactId&amp;gt;drizzle-jdbc&amp;lt;/artifactId&amp;gt;&lt;br /&gt;  &amp;lt;version&amp;gt;0.7&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Change the connection string to the form:    &lt;pre&gt;jdbc:mysql:thin://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;hostname&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;schema&amp;gt;&lt;/pre&gt;(if your tooling needs to do a Class.forName, the driver classname is org.drizzle.jdbc.DrizzleDriver)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Run your test suite&lt;/li&gt;&lt;li&gt;When anything unexpected happens, post a bug report at &lt;a href="http://bugs.launchpad.net/drizzle-jdbc"&gt;launchpad&lt;/a&gt;, preferably with a stack trace and the test case that triggered the error (or send me an email at krummas@gmail.com if you don't have a launchpad account and don't want one).&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Or...&lt;/h3&gt;Tell me about a feature you would really like to see in a JDBC driver! (well, better performance and bug free would of course be nice features, but that is what I want to achieve from the previous section)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-1650085843158422452?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/1650085843158422452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=1650085843158422452' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/1650085843158422452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/1650085843158422452'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2010/07/help-me-test-my-bsd-licensed-jdbc.html' title='Help me test my BSD licensed JDBC driver for Drizzle and MySQL'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-8691985001521194360</id><published>2010-07-04T19:39:00.002+02:00</published><updated>2010-07-04T19:40:40.995+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><title type='text'>Drizzle JDBC 0.7</title><content type='html'>Just pushed Drizzle JDBC 0.7 to the maven repository, it contains bug fixes and features both for the MySQL and Drizzle support;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Support user name and password in Properties when connecting.&lt;/li&gt;&lt;li&gt;A lot of datatype fixes thanks to the guys at &lt;a href="http://www.continuent.com/"&gt;Continuent&lt;/a&gt; and their &lt;a href="http://www.continuent.com/community/tungsten-connector"&gt;Connector&lt;/a&gt; test suite.&lt;/li&gt;&lt;li&gt;Initial implementation of ParameterMetadata.&lt;/li&gt;&lt;li&gt;Fix umlaut bug reported by Christian Peter.&lt;/li&gt;&lt;li&gt;Fix getTables to work properly after bug report from Christian Peter.&lt;/li&gt;&lt;li&gt;Allow zero-length passwords, bug reported by Christian Peter.&lt;/li&gt;&lt;li&gt;Throw proper exception when connection to server times out.&lt;/li&gt;&lt;li&gt;Implementation of setObject with type conversions.&lt;/li&gt;&lt;/ul&gt;The binaries are in the central maven repository, &lt;a href="http://repo1.maven.org/maven2/org/drizzle/jdbc/drizzle-jdbc/0.7/"&gt;http://repo1.maven.org/maven2/org/drizzle/jdbc/drizzle-jdbc/0.7/&lt;/a&gt;. Or, if you use maven, add the following to your pom.xml:&lt;br /&gt;&lt;pre&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt;&amp;lt;groupId&amp;gt;org.drizzle.jdbc&amp;lt;/groupId&amp;gt;&lt;br /&gt;&amp;lt;artifactId&amp;gt;drizzle-jdbc&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&amp;lt;version&amp;gt;0.7&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The code is in &lt;a href="http://launchpad.net/drizzle-jdbc"&gt;launchpad&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-8691985001521194360?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/8691985001521194360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=8691985001521194360' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8691985001521194360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8691985001521194360'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2010/07/drizzle-jdbc-0.html' title='Drizzle JDBC 0.7'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-7820460568854648812</id><published>2010-06-14T20:46:00.000+02:00</published><updated>2010-06-14T20:46:49.521+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Using Jetty and Jersey with Scala</title><content type='html'>Lately I've been playing around with Scala again and I wanted to build a small RESTful web app using &lt;a href="http://jersey.dev.java.net/"&gt;Jersey&lt;/a&gt; running in &lt;a href="http://eclipse.org/jetty"&gt;Jetty&lt;/a&gt; and I couldn't find any working examples online.&lt;br /&gt;&lt;br /&gt;First you need to download and install Scala and &lt;a href="http://code.google.com/p/simple-build-tool/"&gt;SBT&lt;/a&gt;, follow the instructions for SBT on the site. Then you need to create the SBT project (bold stuff is what i typed in);&lt;br /&gt;&lt;code&gt;&lt;pre&gt;$ &lt;b&gt;sbt&lt;/b&gt;&lt;br /&gt;Project does not exist, create new project? (y/N/s) &lt;b&gt;y&lt;/b&gt;&lt;br /&gt;Name: &lt;b&gt;RestWebApp&lt;/b&gt;&lt;br /&gt;Organization: &lt;b&gt;none&lt;/b&gt;&lt;br /&gt;Version [1.0]: &lt;br /&gt;Scala version [2.7.7]: &lt;b&gt;2.8.0.RC5&lt;/b&gt;&lt;br /&gt;sbt version [0.7.4]: &lt;br /&gt;Getting Scala 2.7.7 ...&lt;br /&gt;:: retrieving :: org.scala-tools.sbt#boot-scala&lt;br /&gt; confs: [default]&lt;br /&gt; 2 artifacts copied, 0 already retrieved (9911kB/288ms)&lt;br /&gt;Getting org.scala-tools.sbt sbt_2.7.7 0.7.4 ...&lt;br /&gt;:: retrieving :: org.scala-tools.sbt#boot-app&lt;br /&gt; confs: [default]&lt;br /&gt; 15 artifacts copied, 0 already retrieved (4096kB/149ms)&lt;br /&gt;[success] Successfully initialized directory structure.&lt;br /&gt;Getting Scala 2.8.0.RC5 ...&lt;br /&gt;downloading http://repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.8.0.RC5/scala-compiler-2.8.0.RC5.jar ...&lt;br /&gt; [SUCCESSFUL ] org.scala-lang#scala-compiler;2.8.0.RC5!scala-compiler.jar (92356ms)&lt;br /&gt;downloading http://repo1.maven.org/maven2/org/scala-lang/scala-library/2.8.0.RC5/scala-library-2.8.0.RC5.jar ...&lt;br /&gt; [SUCCESSFUL ] org.scala-lang#scala-library;2.8.0.RC5!scala-library.jar (61762ms)&lt;br /&gt;:: retrieving :: org.scala-tools.sbt#boot-scala&lt;br /&gt; confs: [default]&lt;br /&gt; 2 artifacts copied, 0 already retrieved (14497kB/49ms)&lt;br /&gt;[info] Building project RestWebApp 1.0 against Scala 2.8.0.RC5&lt;br /&gt;[info]    using sbt.DefaultProject with sbt 0.7.4 and Scala 2.7.7&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Now, you need to set up the dependencies for jersey and jetty, in the file project/build/RestWebApp.scala like this;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;import sbt._&lt;br /&gt;&lt;br /&gt;class RestWebAppProject(info: ProjectInfo) extends DefaultProject(info)&lt;br /&gt;{&lt;br /&gt;  val jersey = "com.sun.jersey" % "jersey-server" % "1.2"&lt;br /&gt;  val jerseyJson = "com.sun.jersey" % "jersey-json" % "1.2"&lt;br /&gt;  val jetty = "org.eclipse.jetty" % "jetty-server" % "8.0.0.M0"&lt;br /&gt;  val jettyServlet = "org.eclipse.jetty" % "jetty-servlet" % "8.0.0.M0"&lt;br /&gt;&lt;br /&gt;  val javanetDeps = "javanetDeps" at "http://download.java.net/maven/2/"&lt;br /&gt;}&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Now, in your sbt console;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&gt; &lt;b&gt;reload&lt;/b&gt;&lt;br /&gt;[info] Recompiling project definition...&lt;br /&gt;[info]    Source analysis: 1 new/modified, 0 indirectly invalidated, 0 removed.&lt;br /&gt;[info] Building project RestWebApp 1.0 against Scala 2.8.0.RC5&lt;br /&gt;[info]    using RestWebAppProject with sbt 0.7.4 and Scala 2.7.7&lt;br /&gt;&gt; &lt;b&gt;update&lt;/b&gt;&lt;br /&gt;[info] &lt;br /&gt;[info] == update ==&lt;br /&gt;[info] :: retrieving :: none#restwebapp_2.8.0.RC5 [sync]&lt;br /&gt;[info]  confs: [compile, runtime, test, provided, system, optional, sources, javadoc]&lt;br /&gt;[info]  20 artifacts copied, 0 already retrieved (3745kB/97ms)&lt;br /&gt;[info] == update ==&lt;br /&gt;[success] Successful.&lt;br /&gt;[info] &lt;br /&gt;[info] Total time: 1 s, completed Jun 14, 2010 8:31:40 PM&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now you are good to go, create a file in src/main/scala/something.scala:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;package marcus.test&lt;br /&gt;&lt;br /&gt;import javax.servlet.http.{HttpServletRequest, HttpServletResponse}&lt;br /&gt;import javax.servlet.ServletException&lt;br /&gt; &lt;br /&gt;import java.io.IOException&lt;br /&gt; &lt;br /&gt;import org.eclipse.jetty.server.{Server, Request}&lt;br /&gt;import org.eclipse.jetty.server.handler.AbstractHandler&lt;br /&gt;import org.eclipse.jetty.server.nio.SelectChannelConnector&lt;br /&gt;import org.eclipse.jetty.servlet.{ServletHolder, ServletContextHandler}&lt;br /&gt;import com.sun.jersey.spi.container.servlet.ServletContainer&lt;br /&gt;&lt;br /&gt;import javax.ws.rs.{GET, Produces, Path}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;object WebRunner {&lt;br /&gt;  def main(args: Array[String]) {&lt;br /&gt;&lt;br /&gt;    val server = new Server(8080)&lt;br /&gt;    val connector = new SelectChannelConnector()&lt;br /&gt;    server.addConnector(connector)&lt;br /&gt;    &lt;br /&gt;    val holder:ServletHolder = new ServletHolder(classOf[ServletContainer])&lt;br /&gt;    holder.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",&lt;br /&gt;                            "com.sun.jersey.api.core.PackagesResourceConfig")&lt;br /&gt;    holder.setInitParameter("com.sun.jersey.config.property.packages",&lt;br /&gt;                            "marcus.test")&lt;br /&gt;    val context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS)&lt;br /&gt;    context.addServlet(holder, "/*")&lt;br /&gt;    server.start&lt;br /&gt;    server.join&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@Path("/helloworld")&lt;br /&gt;class TestResource {&lt;br /&gt;  @GET&lt;br /&gt;  def hello() = {&lt;br /&gt;    "HELLO!!"&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;and in your sbt console:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&gt; compile&lt;br /&gt;...&lt;br /&gt;&gt; run&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;and visit http://localhost:8080/helloworld and you should see "HELLO!!". Note that in a real project you might want to separate the classes in different files etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-7820460568854648812?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/7820460568854648812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=7820460568854648812' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/7820460568854648812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/7820460568854648812'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2010/06/using-jetty-and-jersey-with-scala.html' title='Using Jetty and Jersey with Scala'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-2945263993527779690</id><published>2010-04-05T20:28:00.001+02:00</published><updated>2010-04-05T20:28:40.169+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><title type='text'>Drizzle JDBC 0.6</title><content type='html'>I just pushed up Drizzle JDBC 0.6 to the &lt;a href="http://jdbc.drizzle.org/mavenrepo/releases/org/drizzle/jdbc/drizzle-jdbc/0.6/"&gt;maven repo&lt;/a&gt;, should be in the central repository real soon. &lt;br /&gt;&lt;br /&gt;Biggest changes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Fix setObject, handle null properly&lt;/li&gt;&lt;li&gt;Fix bug &lt;a href="https://bugs.launchpad.net/drizzle-jdbc/+bug/501443"&gt;501443&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Fix bug &lt;a href="https://bugs.launchpad.net/drizzle-jdbc/+bug/501452"&gt;501452&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Default to MySQL protocol when connecting to Drizzle&lt;/li&gt;&lt;li&gt;Remove unused code&lt;/li&gt;&lt;li&gt;Default to single-threaded operation&lt;/li&gt;&lt;li&gt;Rename org.drizzle.jdbc.Driver to org.drizzle.jdbc.DrizzleDriver&lt;/li&gt;&lt;li&gt;Lots of protocol performance improvements - both faster and uses less memory (&lt;a href="http://www.yourkit.com/"&gt;YourKit&lt;/a&gt; rules!)&lt;/li&gt;&lt;li&gt;Prepared statement performance increased &lt;i&gt;alot&lt;/i&gt; - uses less memory and is faster&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-2945263993527779690?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/2945263993527779690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=2945263993527779690' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/2945263993527779690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/2945263993527779690'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2010/04/drizzle-jdbc-06.html' title='Drizzle JDBC 0.6'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-4351052504628202374</id><published>2010-03-16T11:22:00.001+01:00</published><updated>2010-03-16T11:34:05.208+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><title type='text'>Drizzle Hibernate Dialect</title><content type='html'>I just built a &lt;a href="http://www.hibernate.org"&gt;hibernate&lt;/a&gt; dialect for drizzle:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;bzr branch lp:~krummas/+junk/drizzledialect&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Drop the file in your project and set;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;hibernate.dialect=org.drizzle.hibernate.dialect.DrizzleDialect&lt;br /&gt;hibernate.connection.url=jdbc:drizzle://10.100.100.50:3307/somedb&lt;br /&gt;hibernate.connection.driver_class=org.drizzle.jdbc.DrizzleDriver&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;And you are ready to go. Preferably use it with the &lt;a href="http://jdbc.drizzle.org/mavenrepo/snapshots/org/drizzle/jdbc/drizzle-jdbc/0.6-SNAPSHOT/"&gt;latest drizzle-jdbc snapshot&lt;/a&gt;. Please try it out and let me know how it works.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-4351052504628202374?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/4351052504628202374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=4351052504628202374' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4351052504628202374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4351052504628202374'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2010/03/drizzle-hibernate-dialect.html' title='Drizzle Hibernate Dialect'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-5648485693078122299</id><published>2010-01-25T15:43:00.000+01:00</published><updated>2010-01-25T15:43:10.430+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rabbitmq'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='rabbitreplication'/><category scheme='http://www.blogger.com/atom/ns#' term='librabbitmq'/><title type='text'>Replicating transactions directly to RabbitMQ</title><content type='html'>Previously RabbitReplication tailed the transaction log provided by Drizzle and then the Java application sent the protobuf serialized transaction to RabbitMQ. Now it is possible to skip the transaction log file and send the transaction directly to the RabbitMQ server without the extra step of storing it in a file first.&lt;br /&gt;&lt;br /&gt;The code is available at&amp;nbsp;&lt;a href="https://code.launchpad.net/~krummas/drizzle/rabbitmq_log"&gt;https://code.launchpad.net/~krummas/drizzle/rabbitmq_log&lt;/a&gt;&amp;nbsp;and to build it with rabbitmq support you need to install &lt;a href="http://hg.rabbitmq.com/rabbitmq-c/"&gt;librabbitmq&lt;/a&gt;&amp;nbsp;which is a bit tricky;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Installing librabbitmq&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Install &lt;/span&gt;&lt;a href="http://mercurial.selenic.com/"&gt;&lt;span style="font-family: inherit;"&gt;mercurial&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://mercurial.selenic.com/"&gt;&lt;/a&gt;Branch the librabbitmq code: &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;hg clone http://hg.rabbitmq.com/rabbitmq-c/&lt;/span&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;Branch the rabbitmq codegen repo into a subdirectory called codegen in the rabbitmq-c directory:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;cd rabbitmq-c&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;hg clone&amp;nbsp;http://hg.rabbitmq.com/rabbitmq-codegen/ codegen&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Run autoconf like this: &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;autoreconf -i&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Run the configure script&lt;/li&gt;&lt;li&gt;make&lt;/li&gt;&lt;li&gt;make install&lt;/li&gt;&lt;/ol&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Build Drizzle&lt;/span&gt;&lt;br /&gt;When librabbitmq is installed, build drizzle like this:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;bzr branch lp:~krummas/drizzle/rabbitmq-log&lt;/span&gt;&lt;/li&gt;&lt;li&gt;config/autorun.sh&lt;/li&gt;&lt;li&gt;./configure --with-rabbitmq-log-plugin&lt;/li&gt;&lt;li&gt;make&lt;/li&gt;&lt;li&gt;make install&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;and it is done!&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Start Drizzle with RabbitMQ support&lt;/span&gt;&lt;/div&gt;&lt;div&gt;First, you can run drizzled with a --help flag to see the options available, they are all prefixed with --rabbitmq-log-XYZ.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The default values for the parameters makes drizzle connect to localhost as "guest" and replicate to an exchange called ReplicationExchange. Start it like this to replicate changes to a rabbitmq on localhost:&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$ sbin/drizzled&amp;nbsp;--default-replicator-enable&amp;nbsp;--rabbitmq-log-enable&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;The other available options are described in --help&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-5648485693078122299?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/5648485693078122299/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=5648485693078122299' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/5648485693078122299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/5648485693078122299'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2010/01/replicating-transactions-directly-to.html' title='Replicating transactions directly to RabbitMQ'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-7453350568165691596</id><published>2010-01-16T20:37:00.003+01:00</published><updated>2010-01-16T20:39:49.636+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='rabbitreplication'/><category scheme='http://www.blogger.com/atom/ns#' term='infinispan'/><title type='text'>Drizzle to Infinispan replication and a small code walkthrough</title><content type='html'>This post aims to explain how to build your own key/value-store applier in RabbitReplication by walking through the new&amp;nbsp;&lt;a href="http://www.jboss.org/infinispan"&gt;Infinispan&lt;/a&gt; support as an example.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-large;"&gt;Infinispan&lt;/span&gt;&lt;br /&gt;Infinispan is a "distributed, highly available data grid platform" and it exposes a &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt;&amp;nbsp;interface where it is possible to manipulate the data in infinispan. For example it is a simple HTTP PUT method to store new data and a HTTP DELETE does exactly what you expect. The data is stored under resources, for RabbitReplication the data is stored under /&lt;schema.table&gt;&amp;lt;schema.table&amp;gt;/&amp;lt;key&amp;gt;. This means you can view the data in infinispan using a browser.&lt;/schema.table&gt;&lt;br /&gt;&lt;schema.table&gt;&lt;key&gt;&lt;br /&gt;&lt;/key&gt;&lt;/schema.table&gt;&lt;br /&gt;&lt;schema.table&gt;&lt;key&gt;When I implemented the Infinispan support, I simply dropped the .war file in the webapps directory of a jetty installation and started it.&amp;nbsp;Since Infinispan has a REST interface, the client library can be any HTTP client, I picked the &lt;a href="https://jersey.dev.java.net/"&gt;Jersey REST&lt;/a&gt; client since it is incredibly easy to use.&lt;/key&gt;&lt;/schema.table&gt;&lt;br /&gt;&lt;schema.table&gt;&lt;key&gt;&lt;br /&gt;&lt;/key&gt;&lt;/schema.table&gt;&lt;br /&gt;&lt;schema.table&gt;&lt;key&gt;&lt;span style="font-size: x-large;"&gt;Customizing RabbitReplication&lt;/span&gt;&lt;br /&gt;RabbitReplication uses &lt;a href="http://code.google.com/p/google-guice/"&gt;Guice&lt;/a&gt; internally for dependency injection, so, to use another KeyValue store you need to create your own Module for configuration. I'll show an example below.&lt;br /&gt;&lt;br /&gt;To add support for a new key/value store, you need to implement an interface,&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: small;"&gt;org.drizzle.replication.transformer.objectstores.KeyValueStoreClient&lt;/span&gt;&lt;/span&gt; (&lt;a href="http://bazaar.launchpad.net/~krummas/rabbitreplication/trunk/annotate/head:/src/org/drizzle/replication/transformer/objectstores/KeyValueStoreClient.java"&gt;here&lt;/a&gt;). It is a quite straight-forward add/get/remove interface. Look at the infinispan implementation (&lt;a href="http://bazaar.launchpad.net/~krummas/rabbitreplication/trunk/annotate/head:/src/org/drizzle/replication/transformer/objectstores/InfinispanStoreClient.java"&gt;here&lt;/a&gt;) for an example. Note the @Inject on the constructor, it tells guice that the WebResource parameter should be injected when it constructs the object. You will need to put the rabbitreplication.jar file on your classpath when building your stuff.&lt;/key&gt;&lt;/schema.table&gt;&lt;br /&gt;&lt;schema.table&gt;&lt;key&gt;&lt;br /&gt;&lt;/key&gt;&lt;/schema.table&gt;&lt;br /&gt;&lt;schema.table&gt;&lt;key&gt;Guice is configured in modules where you bind() an interface to an implementation, so, to configure guice to use a new KeyValueStore, we need to bind()&amp;nbsp;the KeyValueStoreClient interface to&amp;nbsp;the new implementation. Look at the infinispan module (&lt;a href="http://bazaar.launchpad.net/~krummas/rabbitreplication/trunk/annotate/head:/src/org/drizzle/replication/InfinispanModule.java"&gt;here&lt;/a&gt;) for an example how to do it, the method annotated with @Provides is called by guice when it needs to create a KeyValueStoreClient.&lt;/key&gt;&lt;/schema.table&gt;&lt;br /&gt;&lt;br /&gt;To tell RabbitReplication to use your new module, you simply edit your configuration file, and set where the new Module is located, see &lt;a href="http://bazaar.launchpad.net/~krummas/rabbitreplication/trunk/annotate/head:/objectslave.properties.sample"&gt;this&lt;/a&gt; example. If you need to configure your new client, simply add the properties in the config file, guice will bind every property in the file to @Named(...) strings, check the Infinispan module provider method for an example how to use it.&lt;br /&gt;&lt;br /&gt;Now, build your code into a jar, drop the jar in the lib/ directory of rabbitreplication and start RabbitReplication like this; &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;bin/start.sh config/someconf.properties &lt;/span&gt;&lt;span style="font-family: inherit;"&gt;- the config file should have the&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;custom_module &lt;/span&gt;&lt;span style="font-family: inherit;"&gt;set to the name of your new module.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-large;"&gt;Downloading and installing&lt;/span&gt;&lt;br /&gt;Best way to use rabbitreplication is still to branch the code from launchpad (lp:rabbitreplication) and then write ant in the base directory, this will create a .zip and a .tgz in the dist directory. You can also download the binaries &lt;a href="http://marcus.no-ip.biz/rabbitreplication-0.1.tgz"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Unpack the distribution file&lt;/li&gt;&lt;li&gt;Copy a config file from .sample to .properties in the config directory and edit the file to your liking. objectslave.properties.sample is the sample you want to look at if you want to try out Infinispan.&lt;/li&gt;&lt;li&gt;Start rabbitreplication by executing &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;bin/start.sh config/yourconf.properties&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: inherit;"&gt;Look at the previous posts on rabbitreplication to find out how to start a master etc.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-7453350568165691596?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/7453350568165691596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=7453350568165691596' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/7453350568165691596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/7453350568165691596'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2010/01/drizzle-to-infinispan-replication-and.html' title='Drizzle to Infinispan replication and a small code walkthrough'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-3235910392150711119</id><published>2010-01-08T20:54:00.001+01:00</published><updated>2010-01-08T20:58:05.688+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='rabbitreplication'/><category scheme='http://www.blogger.com/atom/ns#' term='cassandra'/><title type='text'>Multi threaded replication appliers</title><content type='html'>Lately I've been working on a transaction reducer to be able to multi thread the applier. Basic idea is to reduce the transaction to only affect one row with one statement, when that is the case, we can have a thread pool doing the actual persisting of the statements (of course it has some drawbacks as well, more about those later). This approach is particularly interesting for NoSQL appliers.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-large;"&gt;Reducing transactions&lt;/span&gt;&lt;br /&gt;The &lt;a href="http://www.jpipes.com/index.php?/archives/299-Drizzle-Replication-The-Transaction-Log.html"&gt;transaction log&lt;/a&gt; in drizzle contains a list of statements. Each statement contains a list of records, where each record contains information about what changed on &lt;b&gt;one&lt;/b&gt;&amp;nbsp;row in the master. One example transaction could look like something like this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;transaction_context {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;server_id: 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;transaction_id: 10&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;start_timestamp: 1262812100381445&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;end_timestamp: 1262812153799963&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;statement {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;type: INSERT&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;start_timestamp: 1262812100381446&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;end_timestamp: 1262812134317464&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;insert_header {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;table_metadata {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;schema_name: "unittests"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;table_name: "test1"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;field_metadata {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;type: INTEGER&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;name: "id"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;field_metadata {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;type: VARCHAR&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;name: "test"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;field_metadata {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;type: VARCHAR&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;name: "ignored"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;insert_data {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;segment_id: 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;end_segment: true&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "78"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "a"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "b"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "79"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "a"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "b"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "87"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "a"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "b"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;statement {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;type: UPDATE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;start_timestamp: 1262812134317466&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;end_timestamp: 1262812151669387&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;update_header {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;table_metadata {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;schema_name: "unittests"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;table_name: "test1"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;key_field_metadata {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;type: INTEGER&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;name: "id"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;set_field_metadata {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;type: VARCHAR&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;name: "test"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;update_data {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;segment_id: 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;end_segment: true&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;key_value: "85"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;after_value: "test"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;statement {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;type: DELETE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;start_timestamp: 1262812151669389&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;end_timestamp: 1262812153799963&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;delete_header {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;table_metadata {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;schema_name: "unittests"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;table_name: "test1"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;key_field_metadata {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;type: INTEGER&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;name: "id"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;delete_data {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;segment_id: 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;end_segment: true&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;key_value: "81"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Or in SQL:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;BEGIN;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (78, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (79, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (80, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (81, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (82, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (83, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (84, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (85, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (86, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (87, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;UPDATE unittests.table1 set test = "test" WHERE id = 85;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;DELETE FROM unittests.table1 WHERE id = 81;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;COMMIT;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;I.e. a number of inserted rows, one updated and one deleted. If we could exploit this and make sure that every record in the transaction &lt;b&gt;only affects one row&lt;/b&gt;&amp;nbsp;then each row is totally independent from all other records in the transaction and we could then have a pool of threads applying the transaction.&lt;br /&gt;&lt;br /&gt;So, if i reduce the above transaction like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;TransactionReducer reducer = new DrizzleTransactionReducer();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;TransactionMessage.Transaction txn =&amp;nbsp;getNextTransaction();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;TransactionMessage.Transaction t = reducer.reduce(txn);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I get this transaction:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;transaction_context {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;server_id: 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;transaction_id: 10&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;start_timestamp: 1262812100381445&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;end_timestamp: 1262812153799963&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;statement {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;type: INSERT&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;start_timestamp: 1262812100381446&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;end_timestamp: 1262812134317464&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;insert_header {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;table_metadata {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;schema_name: "unittests"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;table_name: "test1"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;field_metadata {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;type: INTEGER&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;name: "id"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;field_metadata {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;type: VARCHAR&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;name: "test"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;field_metadata {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;type: VARCHAR&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;name: "ignored"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;insert_data {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;segment_id: 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;end_segment: true&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "78"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "a"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "b"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "79"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "a"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "b"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "80"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "a"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "b"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "82"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "a"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "b"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "83"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "a"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "b"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "84"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "a"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "b"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "85"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "test"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "b"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "86"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "a"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "b"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;record {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "87"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "a"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;insert_value: "b"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;div&gt;Or, in SQL:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;BEGIN;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (78, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (79, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (80, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (82, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (83, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (84, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (85, "test","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (86, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;INSERT INTO unittests.table1 (id, test, ignored) VALUES (87, "a","b");&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;COMMIT;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I.e. a list of only inserts. This means we can apply the transaction using several threads. Another benefit is that we reduce the total number of records to insert meaning better performance.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Updates and deletes that affect rows outside the transaction are also reduced, for example if, within one transaction, one external row is updated twice, then deleted, only the delete statement will be executed.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-large;"&gt;Drawbacks&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are, of course some drawbacks, for example, if this is used when applying to a database, the applier will not be able to apply the transaction as a transaction since there is no way of sharing transaction context between several client threads.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-large;"&gt;Using it&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To try it out, branch this repository: lp:~krummas/+junk/transactionreducer and look at the tests file. Should be straight forward to add more tests to see how it handles them.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It will also be available in &lt;a href="http://launchpad.net/rabbitreplication"&gt;RabbitReplication&lt;/a&gt; as a configuration option on the slave. The size of the thread pool and number of client connections will also be configurable.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: x-large;"&gt;Performance&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In theory it should be faster to apply fewer statements using more threads, and the time spent reducing the transaction should easily be less then the time spent doing network I/O etc. I've done a few non-scientific benchmarks using a multi threaded cassandra applier and it takes approximately half the time applying reduced transactions using the multi threaded applier. I will make some proper benchmarks when everything is in place in RabbitReplication.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-3235910392150711119?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/3235910392150711119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=3235910392150711119' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/3235910392150711119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/3235910392150711119'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2010/01/multi-threaded-replication-appliers.html' title='Multi threaded replication appliers'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-8274447879324113285</id><published>2010-01-01T13:30:00.000+01:00</published><updated>2010-01-01T13:30:28.542+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='rabbitmq'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='rabbitreplication'/><category scheme='http://www.blogger.com/atom/ns#' term='memcached'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><category scheme='http://www.blogger.com/atom/ns#' term='cassandra'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='project voldemort'/><title type='text'>2009 and looking forward to 2010</title><content type='html'>So, this is yet another 2009 retrospect with some goals for 2010, I'll do it in list form so someone might actually browse it;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2009:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Main event of 2009 was that i got kid nr 2, Teo.&lt;/li&gt;&lt;li&gt;Ran 1000K despite injuries&lt;/li&gt;&lt;li&gt;Started &lt;a href="http://launchpad.net/drizzle-jdbc"&gt;Drizzle JDBC&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Got excited about programming again and realized I need a new job&lt;/li&gt;&lt;li&gt;Got Drizzle JDBC to version 0.6, not many users yet, so can't say much about the quality (or, one could look at it from another angle, it is bug free! *cough*)&lt;/li&gt;&lt;li&gt;Went to JavaOne, great stuff, probably the last one.&lt;/li&gt;&lt;li&gt;Started a very long parental leave!&lt;/li&gt;&lt;li&gt;Started working a lot on replication-related stuff:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Wrote an extractor and applier Drizzle for &lt;a href="http://www.continuent.com/community/tungsten-replicator"&gt;Tungsten Replicator&lt;/a&gt;&amp;nbsp;- submitted the code and waiting for it to be published&lt;/li&gt;&lt;li&gt;Started my own replication project, &lt;a href="http://launchpad.net/rabbitreplication"&gt;RabbitReplication&lt;/a&gt;&amp;nbsp;- uses RabbitMQ as a transport and can replicate into &lt;a href="http://developian.blogspot.com/2009/11/drizzle-replication-using-rabbitmq-as.html"&gt;Drizzle&lt;/a&gt;, &lt;a href="http://developian.blogspot.com/2009/12/replication-from-drizzle-to-memcached.html"&gt;Memcached, Project Voldemort&lt;/a&gt;, &lt;a href="http://developian.blogspot.com/2009/12/configuration-this-example-replicates.html"&gt;Cassandra&lt;/a&gt; and directly to &lt;a href="http://developian.blogspot.com/2009/12/drizzle-replication-to-websockets.html"&gt;user browsers using websockets&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;"Learned" Haskell and started looking at Erlang.&lt;/li&gt;&lt;li&gt;Read some great books; Java Concurrency In Practice, Real World Haskell, Effective java (like every year) ...&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;2010 goals:&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Continue my long, sweet parental leave (living in Sweden has its benefits)&lt;/li&gt;&lt;li&gt;Run 1500K&lt;/li&gt;&lt;li&gt;&lt;b&gt;Get myself a new job&lt;/b&gt;,&lt;b&gt; &lt;/b&gt;main requirements:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Most importantly, has a high paced startup-feel to it, I want to build stuff, not have meetings about the stuff we could build&lt;/li&gt;&lt;li&gt;Uses open source products&lt;/li&gt;&lt;li&gt;Contributes stuff back to open source communities (or, best of all, has some open source products of their own)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Make RabbitReplication into a proper product&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Create web page&lt;/li&gt;&lt;li&gt;Make regular releases with good documentation&lt;/li&gt;&lt;li&gt;Build support for more column/key-value stores&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Document how to extend it&lt;/li&gt;&lt;li&gt;Clean up the code&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Get Drizzle-JDBC to "1.0" with someone using it in production (given drizzle makes it there). I'm guessing that when Drizzle itself is production ready, the user (and bug-) count will increase.&lt;/li&gt;&lt;li&gt;Learn at least one new programming language (Erlang, I'm looking at you), and build something with it.&lt;/li&gt;&lt;li&gt;Go to at least one conference&lt;/li&gt;&lt;li&gt;Blog more, November and December frequencies have been ok, mainly because I actually had time to build stuff worth blogging about.&lt;/li&gt;&lt;li&gt;Read more books (current reading queue: Erlang programming, SICP, Reread Distributed Systems - Concepts and design, Java Generics and Collections)&lt;/li&gt;&lt;li&gt;Invent a clock with 30 hrs a day to actually manage all the above goals&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-8274447879324113285?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/8274447879324113285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=8274447879324113285' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8274447879324113285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8274447879324113285'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2010/01/2009-and-looking-forward-to-2010.html' title='2009 and looking forward to 2010'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-2760379590073318933</id><published>2009-12-28T21:58:00.001+01:00</published><updated>2009-12-28T22:03:54.271+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='websockets'/><category scheme='http://www.blogger.com/atom/ns#' term='rabbitmq'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='rabbitreplication'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><title type='text'>Drizzle replication to WebSockets</title><content type='html'>I just pushed a WebSocket applier to RabbitReplication, and yes, it is as crazy as it sounds. It works pretty much like all appliers - it consumes drizzle transactions from &amp;nbsp;RabbitMQ, converts them into objects by inspecting annotations, marshalls the object to JSON, and then stores the JSON string. In this case it stores it to a set of websockets. RabbitReplication is deployed as a war file to &lt;a href="http://www.eclipse.org/jetty/"&gt;Jetty 7.01&lt;/a&gt;&amp;nbsp;which supports websockets.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;a href="http://marcus.no-ip.biz:8082/rabbitrepl/"&gt;DEMO&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I set the demo up on my server at home (in Sweden) on a DSL line, so it might be slow, but it should show the idea, all operations are instant when latency is low (if anyone wants to host it at a better place, please let me know). Of course, &lt;b&gt;it requires a WebSocket capable browser&lt;/b&gt; and the only one I know of is &lt;a href="http://www.google.com/chrome"&gt;Google Chrome&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-large;"&gt;It works like this:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;INSERT is executed from the "drizzle client" webapp - totally separate webapp that uses drizzle jdbc to insert/update/delete data.&lt;/li&gt;&lt;li&gt;Drizzle stores the transaction in the database and in the transaction log.&lt;/li&gt;&lt;li&gt;Master extractor extracts the transaction and publishes it to RabbitMQ&lt;/li&gt;&lt;li&gt;Slave applier consumes the transaction from RabbitMQ&lt;/li&gt;&lt;li&gt;Applier transforms the transaction to JSON&lt;/li&gt;&lt;li&gt;Applier writes the JSON to a set of websockets&lt;/li&gt;&lt;li&gt;Javascript voodoo is performed to make it visible&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span style="font-size: x-large;"&gt;Possible real usecases&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The demo app just shows what is possible, but a real use case could be that someone has a drizzle backed forum and want to add some real time post-updates to some front page somewhere. This would be real easy, simply start a new slave configured for WebSocket application (of course&amp;nbsp;&lt;a href="http://launchpad.net/rabbitreplication"&gt;RabbitReplication&lt;/a&gt; is already used for other replication needs :) ), convert the JSON to something that makes sense and they are set! If someone has a cool usecase, please let me know and i'll build a more realistic demo app!&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-2760379590073318933?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/2760379590073318933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=2760379590073318933' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/2760379590073318933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/2760379590073318933'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/12/drizzle-replication-to-websockets.html' title='Drizzle replication to WebSockets'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-719091791682702790</id><published>2009-12-16T18:58:00.008+01:00</published><updated>2009-12-16T19:47:42.522+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rabbitmq'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='rabbitreplication'/><category scheme='http://www.blogger.com/atom/ns#' term='cassandra'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Better replication from drizzle to cassandra</title><content type='html'>&lt;span style="font-size: x-large;"&gt;&lt;span style="font-size: medium;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-size: x-large;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-size: x-large;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;This article describes how one of the replication appliers work in rabbitreplication, namely the HashTransformer which transforms each INSERT/UPDATE into a hashmap which is then stored in a column-family based storage, currently Cassandra. For a better overview of RabbitReplication, go check out earlier posts on the subject here:&amp;nbsp;&lt;a href="http://developian.blogspot.com/"&gt;http://developian.blogspot.com&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size: x-large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-large;"&gt;Configuration&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;This example replicates changes done to a table called test1 in the schema called unittests. RabbitReplication is configured to only replicate the columns id and test (yes, good example, I know...). The column id is used as a key. The following slave configuration is used for this use case:&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;replication_role = hashslave&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;rabbitmq.host = 10.100.100.50&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;rabbitmq.queuename = ReplicationQueue&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;rabbitmq.exchangename = ReplicationExchange&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;rabbitmq.routingkey = ReplicationRoutingKey&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;rabbitmq.password =&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;rabbitmq.username =&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;rabbitmq.virtualhost =&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;hashstore.host = localhost:9160&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;hashstore.type = cassandra&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;hashreplicator.replicate.unittests.test1 = id,test&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;hashreplicator.key.unittests.test1 = id&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;hashreplicator.keycolseparator.unittests.test1 = .&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;The hashreplicator rows are the interresting ones, they describe what columns to replicate, what columns are the primary key and what separator to use between the columns when the key is multi column.&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-size: x-large;"&gt;Example&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Replicating an &lt;b&gt;insert&lt;/b&gt;:&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;drizzle&amp;gt; use unittests&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Reading table information for completion of table and column names&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;You can turn off this feature to get a quicker startup with -A&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Database changed&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;drizzle&amp;gt; desc test1;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;+---------+-------------+------+-----+---------+-------+&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;| Field &amp;nbsp; | Type &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| Null | Key | Default | Extra |&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;+---------+-------------+------+-----+---------+-------+&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;| id &amp;nbsp; &amp;nbsp; &amp;nbsp;| int &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | NO &amp;nbsp; | PRI | NULL &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; |&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;| test &amp;nbsp; &amp;nbsp;| varchar(10) | YES &amp;nbsp;| &amp;nbsp; &amp;nbsp; | NULL &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; |&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;| ignored | varchar(10) | YES &amp;nbsp;| &amp;nbsp; &amp;nbsp; | NULL &amp;nbsp; &amp;nbsp;| &amp;nbsp; &amp;nbsp; &amp;nbsp; |&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;+---------+-------------+------+-----+---------+-------+&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;3 rows in set (0.02 sec)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;drizzle&amp;gt; insert into test1 (id, test) values (300, "firstins");&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Query OK, 1 row affected (0 sec)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Results in the following on the Cassandra side:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;cassandra&amp;gt; get unittests.test1['300']&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;(column=test, value=firstins; timestamp=1260985298391)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;(column=id, value=300; timestamp=1260985298385)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Returned 2 rows.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;Update&lt;/b&gt;&lt;span style="font-size: medium;"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;drizzle&amp;gt; update test1 set test = "updated" where id = 300;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Query OK, 1 row affected (0 sec)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Rows matched: 1 &amp;nbsp;Changed: 1 &amp;nbsp;Warnings: 0&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Gives this in cassandra:&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;cassandra&amp;gt; get unittests.test1['300']&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;(column=test, value=updated; timestamp=1260985526210)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;(column=id, value=300; timestamp=1260985298385)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Returned 2 rows.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Note that the timestamp for the id column is not updated (only changes are updated, not entire rows).&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;Delete&lt;/b&gt;:&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;drizzle&amp;gt; delete from test1 where id = 300;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Query OK, 1 row affected (0 sec)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-size: medium;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;And in Cassandra:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;cassandra&amp;gt; get unittests.test1['300']&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Returned 0 rows.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;That is it, go to http://launchpad.net/rabbitreplication to check out the code, report bugs or suggest features!&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-719091791682702790?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/719091791682702790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=719091791682702790' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/719091791682702790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/719091791682702790'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/12/configuration-this-example-replicates.html' title='Better replication from drizzle to cassandra'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-6857118850014551729</id><published>2009-12-10T20:55:00.000+01:00</published><updated>2009-12-10T20:55:33.995+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='rabbitreplication'/><category scheme='http://www.blogger.com/atom/ns#' term='cassandra'/><title type='text'>Cassandra support in rabbitreplication</title><content type='html'>Just pushed support for replicating into cassandra to&amp;nbsp;&lt;a href="http://launchpad.net/rabbitreplication"&gt;http://launchpad.net/rabbitreplication&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The following format is used:&lt;br /&gt;&lt;b&gt;KeySpace &lt;/b&gt;= schema name from the transaction&lt;br /&gt;&lt;b&gt;ColumnFamily &lt;/b&gt;= table name from the transaction&lt;br /&gt;&lt;b&gt;Column name &lt;/b&gt;= "object" since we only store objects&lt;br /&gt;&lt;b&gt;Key&lt;/b&gt;&amp;nbsp;= the key generated from the object to store, either by using the @Id annotation or by implementing the KeyAware interface&lt;br /&gt;&lt;br /&gt;In the CLI you would type something like this to get the data (drizzle schema name is unittests and table is test1):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;cassandra&amp;gt; get unittests.test1['1']['object']&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;==&amp;gt; (name=object, value={"name":"updated","ssn":1}; timestamp=1260472768425)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-6857118850014551729?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/6857118850014551729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=6857118850014551729' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/6857118850014551729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/6857118850014551729'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/12/cassandra-support-in-rabbitreplication.html' title='Cassandra support in rabbitreplication'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-8017052741478438121</id><published>2009-12-07T20:56:00.000+01:00</published><updated>2009-12-07T20:56:39.083+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='project voldemort'/><title type='text'>Drizzle persistence in Project Voldemort</title><content type='html'>I just built drizzle support into &lt;a href="http://project-voldemort.com/"&gt;Project Voldemort&lt;/a&gt;:&lt;br /&gt;&lt;a href="http://github.com/krummas/voldemort"&gt;http://github.com/krummas/voldemort&lt;/a&gt;&amp;nbsp;- just add&amp;nbsp;&lt;persistence&gt;drizzle&lt;/persistence&gt; in your stores.xml and it should work&lt;br /&gt;&lt;br /&gt;Basically just a cutnpaste of the mysql code, uses drizzle-jdbc (which is included in the git repo).&lt;br /&gt;&lt;br /&gt;To try it out, check out the code from github, execute "ant release" in the base dir and you get binaries in the dist directory.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-8017052741478438121?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/8017052741478438121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=8017052741478438121' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8017052741478438121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8017052741478438121'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/12/drizzle-persistence-in-project.html' title='Drizzle persistence in Project Voldemort'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-1562067800113266631</id><published>2009-12-06T22:15:00.002+01:00</published><updated>2009-12-06T22:32:45.144+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rabbitmq'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='rabbitreplication'/><category scheme='http://www.blogger.com/atom/ns#' term='memcached'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='project voldemort'/><title type='text'>Replication from drizzle to memcached / project voldemort</title><content type='html'>&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;The last few days I've been working on a way to replicate changes from drizzle into a key value store, currently project voldemort and memcached. It is built in my&amp;nbsp;&lt;a href="http://launchpad.net/rabbitreplication"&gt;rabbit replication project&lt;/a&gt;&amp;nbsp;which means that the transactions are transfered over a message bus (rabbitmq currently). The picture below describes an example of how the involved components could be set up (not likely that you want both memcached and project voldemort though):&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_KT0gO50Y6Vc/SxwcTVlCl0I/AAAAAAAAAQo/EkiC2y4f4D4/s1600-h/examplerabbitreplication.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_KT0gO50Y6Vc/SxwcTVlCl0I/AAAAAAAAAQo/EkiC2y4f4D4/s400/examplerabbitreplication.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;Current feature list of rabbitreplication:&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Replication from drizzle into drizzle (or any database with a JDBC driver) / memcached / project voldemort.&lt;/li&gt;&lt;li&gt;Map inserts and updates onto java objects using annotated classes (see below for example).&lt;/li&gt;&lt;li&gt;Two different ways of marshalling objects, JSON ond Java object serialization&lt;/li&gt;&lt;li&gt;Full control over how the key is generated (just implement the KeyAware interface in your target object)&lt;/li&gt;&lt;li&gt;Simple interface to build new marshallers.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Simple interface to build new object stores.&lt;/li&gt;&lt;li&gt;Simple interface to build new transports. (Will blog these extension points later)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;Example:&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;The class below will catch any statements on the table unittests.test1 and take the column "id" and set it on the ssn field, and it will take the "test" column and set it on the name field. It will use the field annotated with @Id as key in the store and use the JSONMarshaller to marshal the object.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;@Entity(schema = "unittests", table = "test1", marshaller = JSONMarshaller.class)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;public class ExampleRepl {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;@Id&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;@Column("id")&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;private int ssn;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;@Column("test")&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;private String name;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/*...*/&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-weight: normal;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;Add this to your config to use it:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;managed_classes = org.drizzle.managedclasses.ExampleRepl, ...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: inherit;"&gt;Then you just start your slave like this:&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;java -jar replication.jar objectslave.properties&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: inherit;"&gt;You need to put your managed classes on the classpath (drop them in the lib dir)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: inherit;"&gt;(See earlier posts about rabbitreplication on how to get started)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: inherit;"&gt;Todo:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: normal;"&gt;Clean up configuration, quite messy right now&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: normal;"&gt;Write blogposts about how to roll your own transport/marshalling/key-value store implementations&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: normal;"&gt;Increase test suite and set up hudson for continuous integration&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: normal;"&gt;Write proper usage documentation&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: normal;"&gt;Build more backends, marshallers and transports, evolve apis&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: normal;"&gt;Write a MySQL binlog master (needs to transform mysql binlog into drizzle's protobuf based log, not even sure it is possible)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: normal;"&gt;Create a way to not have to write code on the slave (pin tables to a hash and store it)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: normal;"&gt;...&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Getting involved&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: normal;"&gt;Get the code, bzr branch lp:rabbitreplication&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: normal;"&gt;Use it, give me feedback (krummas@gmail.com) &amp;lt;- most important!&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Download&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://marcus.no-ip.biz/rabbitrepl.zip"&gt;http://marcus.no-ip.biz/rabbitrepl.zip&lt;/a&gt;&amp;nbsp;&lt;span style="font-weight: normal;"&gt;(yes, i will soon set up a proper download page).&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/b&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-1562067800113266631?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/1562067800113266631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=1562067800113266631' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/1562067800113266631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/1562067800113266631'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/12/replication-from-drizzle-to-memcached.html' title='Replication from drizzle to memcached / project voldemort'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_KT0gO50Y6Vc/SxwcTVlCl0I/AAAAAAAAAQo/EkiC2y4f4D4/s72-c/examplerabbitreplication.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-6738686823245525312</id><published>2009-11-30T21:52:00.000+01:00</published><updated>2009-11-30T21:52:05.103+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rabbitmq'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Update of RabbitMQ Replicator</title><content type='html'>The little Drizzle RabbitMQ replicator I built last week got quite popular (and even &amp;nbsp;users!) so I decided to work a bit more on it. These are the changes:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Moved it to a real project on launchpad (&lt;a href="http://launchpad.net/rabbitreplication"&gt;http://launchpad.net/rabbitreplication&lt;/a&gt;)&amp;nbsp;&lt;/li&gt;&lt;li&gt;Store transaction log position on master so that a transaction is never sent twice over the wire.&lt;/li&gt;&lt;li&gt;Major internal refactorings, start using google guice for IoC&lt;/li&gt;&lt;li&gt;Make the transport pluggable, it should now be easy to write your own transport and swap out rabbitmq, JMS anyone?&lt;/li&gt;&lt;li&gt;Alot more configurations for rabbitmq, see &lt;a href="http://bazaar.launchpad.net/~krummas/rabbitreplication/trunk/annotate/head:/master.properties"&gt;example config&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;User Guide:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Download binaries &lt;a href="http://marcus.no-ip.biz/rabbitrepl.zip"&gt;here&lt;/a&gt;&amp;nbsp;(or check out code: bzr branch lp:rabbitreplication)&lt;/li&gt;&lt;li&gt;Unzip on master&lt;/li&gt;&lt;li&gt;Edit master.properties to reflect your environment (hope the config vars are self-explanatory, let me know if there are any problems)&lt;/li&gt;&lt;li&gt;Start the master: &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;java -jar replication.jar master.properties&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Unzip on slave&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Edit slave.properties&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Start the slave:&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;java -jar replication.jar slave.properties&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Watch changes replicate, report issues to me (krummas@gmail.com)&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;b&gt;Todo/Ideas:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;I'm thinking about using this code to build a framework for replicating changes from Drizzle into other storage forms, for example Hadoop/hbase or Cassandra. My thinking is that it could be useful for moving data that is very hot into a faster storage without changing your application too much. This might need business logic implemented on the "slave" (saying for example that this column should be stored and this should be ignored), and that is what I'm thinking could be built quite nicely using a framework (a DSL could be handy).&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Please let me know if this has been done somewhere or if it is a stupid idea!&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-6738686823245525312?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/6738686823245525312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=6738686823245525312' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/6738686823245525312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/6738686823245525312'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/11/update-of-rabbitmq-replicator.html' title='Update of RabbitMQ Replicator'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-4138410905283927195</id><published>2009-11-23T21:38:00.000+01:00</published><updated>2009-11-23T21:38:06.613+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rabbitmq'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Drizzle Replication using RabbitMQ as a transport</title><content type='html'>Having spent a bit of time learning how the transaction log in drizzle works (and it is incredibly easy to work with), I got an idea to use &lt;a href="http://www.rabbitmq.com/"&gt;RabbitMQ&lt;/a&gt;&amp;nbsp;as a transport. RabbitMQ is an implementation of the &lt;a href="http://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol"&gt;AMQP&lt;/a&gt;&amp;nbsp;standard in &lt;a href="http://erlang.org/"&gt;Erlang&lt;/a&gt;, so it must be awesome.&lt;br /&gt;&lt;br /&gt;It works like this; on the master, a java app is simply tailing the transaction log, sending all new transactions, in raw format, to a rabbitmq server.&lt;br /&gt;&lt;br /&gt;The slave(s) are connected to the messaging server and are guaranteed to get the raw messages. When the slave gets the message, it transforms it to a JDBC prepared statement and executes every statement as a batch operation. The reason I use prepared statements and batch operations is that I get a lot for free from the JDBC driver, for example correct escaping of strings etc, and I can also enable the &lt;a href="http://developian.blogspot.com/2009/07/drizzle-jdbc-04-rewrite-batch-handler.html"&gt;rewrite batch handler&lt;/a&gt;&amp;nbsp;feature to get a great performance boost.&lt;br /&gt;&lt;br /&gt;Another great thing we get for free by using rabbitmq is the fail-safety, if an exception is thrown in the slave, the message is not acknowledged and it will be retried later.&lt;br /&gt;&lt;br /&gt;Being able to write something like this in a few hours really shows how powerful the drizzle replication system is. It will be one of the killer features.&lt;br /&gt;&lt;br /&gt;There is one issue i really need to fix, namely that the master does not keep track of which transactions it has sent over the wire, so it will resend all transactions in the log every time it is restarted. Of course, since this was written in a short time, there are probably lots of other issues as well. If you want a real replication solution, go check out &lt;a href="http://www.continuent.com/community/tungsten-replicator"&gt;Tungsten Replicator&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If anyone wants to contribute, the code is on launchpad:&amp;nbsp;&lt;a href="https://code.launchpad.net/~krummas/+junk/rabbitmq-replication"&gt;https://code.launchpad.net/~krummas/+junk/rabbitmq-replication&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you simply want to try it out, get the binaries here:&amp;nbsp;&lt;a href="http://marcus.no-ip.biz/rabbitrepl.zip"&gt;http://marcus.no-ip.biz/rabbitrepl.zip&lt;/a&gt;&amp;nbsp;To start it, you do &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;java -jar replication.jar master.properties&lt;/span&gt; - just make sure you edit the .properties files before starting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-4138410905283927195?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/4138410905283927195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=4138410905283927195' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4138410905283927195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4138410905283927195'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/11/drizzle-replication-using-rabbitmq-as.html' title='Drizzle Replication using RabbitMQ as a transport'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-4577436122316659452</id><published>2009-11-17T21:08:00.000+01:00</published><updated>2009-11-17T21:08:39.029+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Tungsten Replicator and Drizzle howto</title><content type='html'>Last week I got a few hours to spend on making an extractor for Tungsten Replicator which works against the Drizzle transaction log. This post aims to explain how you use it to replicate changes between drizzle instances.&lt;br /&gt;&lt;br /&gt;To get a better understanding of the drizzle replication system, please go read the article on Jay Pipes blog,&amp;nbsp;&lt;a href="http://www.jpipes.com/index.php?/archives/299-Drizzle-Replication-The-Transaction-Log.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Get the code&lt;/b&gt;&lt;br /&gt;First, you need to check the code out from the tungsten sourceforge repo, like this:&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;svn co https://tungsten.svn.sourceforge.net/svnroot/tungsten/trunk&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Then you need to download my patch,&amp;nbsp;&lt;a href="http://marcus.no-ip.biz/drizzle_support.patch.gz"&gt;here&lt;/a&gt;. Unzip it in the trunk/replicator directory and apply it like this:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;patch -p0 &amp;lt; drizzle_support.patch&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;This patch includes all dependencies and the applier I wrote about in the last post.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Build it&lt;/b&gt;&lt;br /&gt;Now you need to build tungsten, change working dir to the replicator directory and write&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ant&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;If you got test errors, you can run &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ant allExceptJunit&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; to skip the tests (there are some environment configurations needed to get the test suite running).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The artifacts end up in the build/ directory.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Get and build Drizzle&lt;/b&gt;&lt;br /&gt;Follow the instructions on the drizzle wiki, &lt;a href="http://drizzle.org/wiki/Compiling"&gt;http://drizzle.org/wiki/Compiling&lt;/a&gt;, just make sure that you pass&amp;nbsp;--with-transaction-log-plugin when you ./configure drizzle.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Start Drizzle&lt;/b&gt;&lt;br /&gt;Follow the instructions on the drizzle wiki:&amp;nbsp;&lt;a href="http://drizzle.org/wiki/Starting_drizzled"&gt;http://drizzle.org/wiki/Starting_drizzled&lt;/a&gt;&amp;nbsp;and add the parameters&amp;nbsp;--transaction-log-enable --default-replicator-enable when starting drizzled, otherwise you wont get a transaction log.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set up Tungsten Replicator&lt;/b&gt;&lt;br /&gt;Using the binaries built before, read the instructions for MySQL on the Continuent page:&amp;nbsp;&lt;a href="http://www.continuent.com/community/tungsten-replicator/documentation"&gt;http://www.continuent.com/community/tungsten-replicator/documentation&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Then we need to do some changes to the configuration files, for the master (extractor), use&amp;nbsp;&lt;a href="http://marcus.no-ip.biz/replicator.properties.master.drizzle"&gt;this configuration file&lt;/a&gt;&amp;nbsp;as a template. Note that you must change the path to the transaction log. On the slave (applier), use &lt;a href="http://marcus.no-ip.biz/replicator.properties"&gt;this config file&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now you should be good to go, start your drizzle and tungsten instances and watch the changes replicate.&lt;br /&gt;&lt;br /&gt;Note that almost all the involved components (drizzle, drizzle-jdbc, the drizzle extractor and applier) are not recommended for production use yet.&lt;br /&gt;&lt;br /&gt;As always, if you have any questions, shoot me an email (krummas@gmail.com) or ping me on #drizzle @ freenode&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-4577436122316659452?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/4577436122316659452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=4577436122316659452' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4577436122316659452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4577436122316659452'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/11/tungsten-replicator-and-drizzle-howto.html' title='Tungsten Replicator and Drizzle howto'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-2074929926805783531</id><published>2009-10-29T08:29:00.001+01:00</published><updated>2009-10-29T08:37:13.481+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tungsten'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Replication from MySQL to Drizzle using Tungsten Replicator</title><content type='html'>Last week I sat down and created a Drizzle Applier for &lt;a href="http://www.continuent.com/community/tungsten-replicator"&gt;Tungsten Replicator&lt;/a&gt;. This makes it possible to replicate changes from MySQL (for example) to Drizzle. An applier is used to apply changes on a slave. This blog post aims to explain how you could try it out.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Download &lt;a href="http://marcus.no-ip.biz/drizzle_applier.diff"&gt;this&lt;/a&gt; patch&lt;/li&gt;&lt;li&gt;Check out the latest tungsten code: &lt;pre&gt;svn co https://tungsten.svn.sourceforge.net/svnroot/tungsten/trunk/&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Apply the patch: &lt;pre&gt;patch -p0 &amp;lt; drizzle_applier.diff&lt;/pre&gt;in the replicator directory&lt;/li&gt;&lt;li&gt;Build it: &lt;pre&gt;ant&lt;/pre&gt;in the replicator directory. This creates binaries in the replicator/build/ directory.&lt;/li&gt;&lt;li&gt;Follow the instructions in the &lt;a href="http://www.continuent.com/community/tungsten-replicator/documentation"&gt;Tungsten Replicator documentation&lt;/a&gt; to set up the master and the slave (extractor and applier).&lt;/li&gt;&lt;li&gt;Use &lt;a href="http://marcus.no-ip.biz/replicator.properties"&gt;this&lt;/a&gt; properties file as an example for your properties file on the slave (applier).&lt;/li&gt;&lt;li&gt;Download &lt;a href="http://marcus.no-ip.biz/drizzle-jdbc-0.6-SNAPSHOT.jar"&gt;this&lt;/a&gt; version of drizzle jdbc, and put it in the lib/ directory (of the extracted distribution)&lt;/li&gt;&lt;li&gt;Start it up!&lt;/li&gt;&lt;/ol&gt;Until there is a mysqldump-converter (or similar) that can create mysql dumps that can be consumed by drizzle, it will be difficult to get a consistent starting point.&lt;br /&gt;&lt;br /&gt;Note that this is a very early version of both the applier and the jdbc driver, so please report any bugs to me, krummas@gmail.com, attach the log file from the log directory.&lt;br /&gt;&lt;br /&gt;The code has been submitted to Continuent and will hopefully end up in a future official version.&lt;br /&gt;&lt;br /&gt;I'm also currently working on an extractor for drizzle - i.e. making it possible to use Drizzle as a master. Stay tuned for that within a week or so.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-2074929926805783531?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/2074929926805783531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=2074929926805783531' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/2074929926805783531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/2074929926805783531'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/10/replication-from-mysql-to-drizzle-using.html' title='Replication from MySQL to Drizzle using Tungsten Replicator'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-1464292334546171419</id><published>2009-09-28T07:18:00.001+02:00</published><updated>2009-09-28T07:18:23.907+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><title type='text'>Drizzle JDBC 0.5</title><content type='html'>I just pushed Drizzle-JDBC 0.5 to the maven repos, changelog:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;fixes&lt;/li&gt;&lt;ul&gt;&lt;li&gt;setBytes in Blob not working&lt;/li&gt;&lt;li&gt;getTypeName in ResultSetMetaData&lt;/li&gt;&lt;li&gt;create timestamp based on a date field&lt;/li&gt;&lt;li&gt;isBeforeFirst() in ResultSets should return false if it is an empty result set&lt;/li&gt;&lt;li&gt;setObject should support java.util.Date&lt;/li&gt;&lt;li&gt;timestamp bug&lt;/li&gt;&lt;li&gt;if asking for generated keys and no query was executed - return empty result set&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Support "ON DUPLICATE KEY UPDATE" in rewrite insert batch handler&lt;/li&gt;&lt;li&gt;Handle prepared statement placeholders within quotes and comments&lt;/li&gt;&lt;li&gt;Automatically run test suite for mysql as well as drizzle&lt;/li&gt;&lt;li&gt;Strip queries from comments in prepared statements&lt;/li&gt;&lt;li&gt;Use java.nio.ByteBuffer - better performance and cleaner code&lt;/li&gt;&lt;li&gt;More reports in Hudson (history lost though, apparently no way to convert a maven-project to a freestyle-project): &lt;a href="http://marcus.no-ip.biz/hudson/job/drizzle-jdbc-freestyle/"&gt;http://marcus.no-ip.biz/hudson/job/drizzle-jdbc-freestyle/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;It is available in the public maven repository: &lt;a href="http://repo2.maven.org/maven2/org/drizzle/jdbc/drizzle-jdbc/0.5/"&gt;http://repo2.maven.org/maven2/org/drizzle/jdbc/drizzle-jdbc/0.5/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-1464292334546171419?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/1464292334546171419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=1464292334546171419' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/1464292334546171419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/1464292334546171419'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/09/drizzle-jdbc-05.html' title='Drizzle JDBC 0.5'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-547140548251314670</id><published>2009-07-14T22:11:00.005+02:00</published><updated>2009-08-22T19:00:31.154+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Drizzle JDBC 0.4 - Rewrite batch handler</title><content type='html'>I just pushed up Drizzle JDBC 0.4, which, most importantly, contains a rewrite batch handler (I guess much like the one Mark Matthews announced for Connector/J a couple of months ago). It gives the expected 10x+ batch insert improvements, on my laptop I can insert 1M "simple" rows in under 20 seconds.&lt;br /&gt;&lt;br /&gt;It is written as a plugin, so you need to do this to your Connection to enable it:&lt;br /&gt;&lt;pre name="code" class="Java"&gt;if(connection.isWrapperFor(DrizzleConnection.class)) {&lt;br /&gt;DrizzleConnection dc = connection.unwrap(DrizzleConnection.class);&lt;br /&gt;dc.setBatchQueryHandlerFactory(new RewriteParameterizedBatchHandlerFactory());&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;(Yes, it will be possible to configure plugins via the connection string and by setting properties). Please, try it out and report any bugs you find!&lt;br /&gt;&lt;br /&gt;I also wrote a Scala version of the plugin, it is not bundled with the 0.4 release though - if you are interrested, it is on &lt;a href="https://code.launchpad.net/~krummas/+junk/rw-bh-scala-drizzle-jdbc"&gt;Launchpad&lt;/a&gt;. Scala is awesome, hoping to do some more Scala development in the near future.&lt;br /&gt;&lt;br /&gt;This is the changelog for 0.4:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Findbug fixes&lt;/li&gt;&lt;li&gt;Internal refactorings&lt;/li&gt;&lt;li&gt;Make sure all tests pass against both MySQL and Drizzle&lt;/li&gt;&lt;li&gt;Batch handler API cleanups, details &lt;a href="http://drizzle.org/wiki/JDBC/PluginInterfaces#Batch_Query_Handler"&gt;here.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Fix read of 16bit word (by Trond Norbye)&lt;/li&gt;&lt;li&gt;A query rewrite batch handler&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Download 0.4 &lt;a href="http://jdbc.drizzle.org/mavenrepo/releases/org/drizzle/jdbc/drizzle-jdbc/0.4/"&gt;here.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-547140548251314670?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/547140548251314670/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=547140548251314670' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/547140548251314670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/547140548251314670'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/07/drizzle-jdbc-04-rewrite-batch-handler.html' title='Drizzle JDBC 0.4 - Rewrite batch handler'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-5585923381620045604</id><published>2009-06-04T22:04:00.003+02:00</published><updated>2009-06-04T19:07:24.028+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><title type='text'>Pluggable Batch Update Handlers</title><content type='html'>Reading about the awesome batch insert performance blog post by Mark Matthews last week (&lt;a href="http://www.jroller.com/mmatthews/entry/speeding_up_batch_inserts_for"&gt;http://www.jroller.com/mmatthews/entry/speeding_up_batch_inserts_for&lt;/a&gt;) got me thinking, why has this not been done before? Connector/J must be the most deployed JDBC driver in the world and batch inserts are a common use case, why hasn't the community stepped up and implemented the query rewrite feature before? Most likely because it is a complex issue that requires deep knowledge of the rest of the driver. I have been a happy Connector/J user myself for several years and never considered doing something like this.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;To handle this complexity in drizzle-jdbc the batch query functionality is pluggable, i.e. you can implement a small interface and tell the connection to use that implementation. So, if anyone out there has some crazy ideas about how to improve performance of batch inserts/updates, it should be fairly easy.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;First you need to implement the ParameterizedBatchHandler interface, it has two methods:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void addToBatch(ParameterizedQuery query);&lt;br /&gt;int [] executeBatch(Protocol protocol) throws QueryException;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;addToBatch is called when addBatch() is called on the PreparedStatement. I.e. when someone wants to add the current set of parameters in a prepared statement to the current batch - the query parameter contains all the information you need to make something smart.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;executeBatch is called when executeBatch() is called on the PreparedStatement. The protocol sent to this method should be used to send the query to the server (though, you could make new connections to the server, fork up a few threads and send queries to the server in parallel).&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Then, to make the connection use your handler:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Connection connection = DriverManager.getConnection("jdbc:drizzle://localhost:4427/test_units_jdbc");&lt;br /&gt;if(connection.isWrapperFor(DrizzleConnection.class)) {&lt;br /&gt;   DrizzleConnection dc = connection.unwrap(DrizzleConnection.class);&lt;br /&gt;   dc.setBatchQueryHandler(VerrrryFastBatchHandler.class);&lt;br /&gt;}&lt;br /&gt;PreparedStatement ps = connection.prepareStatement("insert into asdf (somecol) values (?)");&lt;br /&gt;ps.setString(1,"aa");&lt;br /&gt;ps.addBatch();&lt;br /&gt;ps.executeBatch();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;The current implementation in drizzle-jdbc simply stores all queries in a list and when doing executeBatch, the queries are sent, one-by-one, to the server. I'm planning on doing a rewrite handler in the near future.&lt;br&gt;&lt;br /&gt;Look at these files for more information:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://bazaar.launchpad.net/~krummas/drizzle-jdbc/trunk/annotate/head%3A/src/main/java/org/drizzle/jdbc/internal/common/ParameterizedBatchHandler.java"&gt;ParameterizedBatchHandler.java&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://bazaar.launchpad.net/~krummas/drizzle-jdbc/trunk/annotate/head%3A/src/main/java/org/drizzle/jdbc/internal/common/DefaultParameterizedBatchHandler.java"&gt;DefaultParameterizedBatchHandler.java&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://bazaar.launchpad.net/~krummas/drizzle-jdbc/trunk/annotate/head%3A/src/test/java/org/drizzle/jdbc/DriverTest.java#L430"&gt;DriverTest.java&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-5585923381620045604?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/5585923381620045604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=5585923381620045604' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/5585923381620045604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/5585923381620045604'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/05/pluggable-batch-update-handlers.html' title='Pluggable Batch Update Handlers'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-8665424453936793324</id><published>2009-06-01T08:53:00.004+02:00</published><updated>2009-06-01T08:54:55.300+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><title type='text'>Drizzle-JDBC 0.3</title><content type='html'>I just pushed up 0.3 of drizzle-jdbc to the maven repository, go &lt;a href="http://jdbc.drizzle.org/mavenrepo/releases/org/drizzle/jdbc/drizzle-jdbc/0.3/"&gt;here&lt;/a&gt; to download. It will soon be synced to the official maven repository.&lt;br&gt;&lt;br /&gt;&lt;br /&gt;Changes from 0.2 to 0.3:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Add the services file to make the driver autoload.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Throw proper JDBC4 SQLExceptions.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Make blobs + getObject() work against new versions of drizzled.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Fix bug with generated keys and prepared statements.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Fix bug with prepared statements and adding parameters several times (fix by Trond Norbye).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Name the packet fetcher thread.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Fix bug with getSchemas() - returned columns in wrong order.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Rework of the packet fetching by Trond.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Pluggable batch query handlers (I'll blog about this soon)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-8665424453936793324?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/8665424453936793324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=8665424453936793324' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8665424453936793324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8665424453936793324'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/06/drizzle-jdbc-03.html' title='Drizzle-JDBC 0.3'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-3887797517412923821</id><published>2009-05-29T14:12:00.002+02:00</published><updated>2009-05-29T14:15:18.477+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='guice'/><category scheme='http://www.blogger.com/atom/ns#' term='javaone'/><title type='text'>JavaOne sessions</title><content type='html'>I'm attending JavaOne this year, it starts on Tuesday. These are the sessions i look forward the most to (in no particular order):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Return of the Puzzlers: Schlock and Awe (TS-5186)&lt;/span&gt;&lt;br /&gt;Josh Bloch and Neal Gafter present a couple of interresting programming puzzles, will be fun.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Effective Java: Still effective after all these years (TS-5217)&lt;/span&gt;&lt;br /&gt;Again, Joshua Bloch. His book "Effective Java" is one of the best programming books i've read.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Java Platform Concurrency Gotchas (TS-4863)&lt;/span&gt;&lt;br /&gt;Concurrency is a difficult issue, this session presents issues with code examples.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ghost in the virtual machine: A reference to references (TS-5245)&lt;/span&gt;&lt;br /&gt;Bob is the author of google guice (see below) and from what I've heard, he is also a great speaker.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Defective Java Code: Mistakes that matter (TS-5335)&lt;/span&gt;&lt;br /&gt;About bugs in java code, static analysis etc.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Drizzle: A new database for the cloud (TS-5410)&lt;/span&gt;&lt;br /&gt;Drizzle is a great project, positive, helpful people.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;JDBC? We don't need no stinkin' JDBC: How LinkedIn scaled with memcached, SOA and a bit of SQL. (TS-4696)&lt;/span&gt;&lt;br /&gt;Always interesting to hear how big companies handle scalability issues really job related for me.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Introduction to Google Guice: The Java Programming language is fun again (TS-5434)&lt;/span&gt;&lt;br /&gt;Google Guice really opened my eyes to what you can do with java, the subject of the talk is so true, it shows what java is capable of and that java can be fun. This is how modern java development should be done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-3887797517412923821?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/3887797517412923821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=3887797517412923821' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/3887797517412923821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/3887797517412923821'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/05/javaone-sessions.html' title='JavaOne sessions'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-1765607009141824651</id><published>2009-05-10T07:14:00.004+02:00</published><updated>2009-05-10T07:32:25.708+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Drizzle-JDBC in central maven repository</title><content type='html'>Now releases of Drizzle-JDBC are in the central &lt;a href="http://maven.apache.org"&gt;maven&lt;/a&gt; repository which makes it very easy to use if you are building your projects with maven (or ant + ivy).&lt;br /&gt;&lt;br /&gt;Just add the following dependency to your pom.xml:&lt;br /&gt;&lt;pre&gt;&amp;lt;dependency&amp;gt;                                                                        &lt;br /&gt; &amp;lt;groupid&amp;gt;org.drizzle.jdbc&amp;lt;/groupid&amp;gt;                                          &lt;br /&gt; &amp;lt;artifactid&amp;gt;drizzle-jdbc&amp;lt;/artifactid&amp;gt;                                        &lt;br /&gt; &amp;lt;version&amp;gt;0.1&amp;lt;/version&amp;gt;                                                       &lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;/pre&gt;&lt;br /&gt;And you are good to go, maven will download the dependencies for you!&lt;br /&gt;&lt;br /&gt;Note, drizzle-jdbc uses &lt;a href="http://slf4j.org"&gt;SLF4J&lt;/a&gt; for logging, so if you don't use that you'll need to add a dependency to one of the logging implementations as well:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;dependency&amp;gt;                                                                        &lt;br /&gt; &amp;lt;groupid&amp;gt;org.slf4j&amp;lt;/groupid&amp;gt;                                          &lt;br /&gt; &amp;lt;artifactid&amp;gt;slf4j-nop&amp;lt;/artifactid&amp;gt;                                        &lt;br /&gt; &amp;lt;version&amp;gt;1.5.6&amp;lt;/version&amp;gt;                                                       &lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-1765607009141824651?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/1765607009141824651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=1765607009141824651' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/1765607009141824651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/1765607009141824651'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/05/drizzle-jdbc-in-public-maven-repository.html' title='Drizzle-JDBC in central maven repository'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-3877511787946725573</id><published>2009-04-27T07:01:00.000+02:00</published><updated>2009-04-27T08:07:10.755+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><title type='text'>jHeidi drizzle support</title><content type='html'>Bill Culp over at &lt;a href="http://jheidi.com/"&gt;jheidi.com&lt;/a&gt; just released a version of jHeidi that supports Drizzle, using &lt;a href="http://launchpad.net/drizzle-jdbc"&gt;drizzle-jdbc&lt;/a&gt;, cool seeing the driver in action! Go try it out.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://2.bp.blogspot.com/_KT0gO50Y6Vc/SfU9t8yD7YI/AAAAAAAAANs/ShRHluFtj6o/s320/drizzlejheidi.png"/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-3877511787946725573?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/3877511787946725573/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=3877511787946725573' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/3877511787946725573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/3877511787946725573'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/04/jheidi-drizzle-support.html' title='jHeidi drizzle support'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_KT0gO50Y6Vc/SfU9t8yD7YI/AAAAAAAAANs/ShRHluFtj6o/s72-c/drizzlejheidi.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-2240488294567751765</id><published>2009-04-21T20:28:00.000+02:00</published><updated>2009-04-21T20:59:52.675+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><title type='text'>Initial MySQL support and the JDBC4 wrapper interface</title><content type='html'>It is now possible to use drizzle-jdbc to execute queries against a MySQL database. The changes needed to support this were very small, the only difference (right now) in the protocol is that the number of commands has been reduced in drizzle, and the server capabilities enum has been modified to mirror the capabilities in drizzle. In the near future drizzle will have a brand new protocol though, so I made the decision to separate the main protocol classes, and share whatever can be shared outside that class.&lt;br /&gt;&lt;br /&gt;To use drizzle-jdbc against MySQL, check this example:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;        try {&lt;br /&gt;            Class.forName("org.drizzle.jdbc.Driver");&lt;br /&gt;        } catch (ClassNotFoundException e) {&lt;br /&gt;            throw new SQLException("Could not load driver");&lt;br /&gt;        }&lt;br /&gt; // lets hope the big O doesnt sue me for using "thin" in the connection string:&lt;br /&gt;        Connection connection = &lt;br /&gt;           DriverManager.getConnection("jdbc:mysql:thin://slaveusr@localhost:3306/test_units_jdbc"); &lt;br /&gt; Statement statement = connection.createStatement();&lt;br /&gt; statement.execute("INSERT INTO a VALUES (1)");&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;JDBC4 introduced the wrapper interface, so that a user of the JDBC driver can access vendor-specific functionality in the driver. To test it, I implemented the COM_BINLOG_DUMP command against MySQL, it works like this:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt; if(connection.isWrapperFor(ReplicationConnection.class))) {&lt;br /&gt;    ReplicationConnection rc = connection.unwrap(ReplicationConnection.class);&lt;br /&gt;           List&amp;lt;RawPacket&amp;gt; rpList = rc.startBinlogDump(891,"mysqld-bin.000001");&lt;br /&gt;       for(RawPacket rp : rpList) {&lt;br /&gt;              for(byte b:rp.getRawBytes()) {&lt;br /&gt;                 System.out.printf("0x%x ",b);&lt;br /&gt;              }&lt;br /&gt;              System.out.printf("\n");&lt;br /&gt;           }&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Of course, this is just a proof-of-concept, it gives you a list of the raw events in the binlog on the server. This is not something really usable, but it shows how to build vendor-specific stuff and access them through the JDBC4 wrapper interface. My plan is to parse the events from the binlog and make them available on a per-request basis so we don't need to store all events from the server binlog in-memory.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-2240488294567751765?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/2240488294567751765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=2240488294567751765' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/2240488294567751765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/2240488294567751765'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/04/initial-mysql-support-and-jdbc4-wrapper.html' title='Initial MySQL support and the JDBC4 wrapper interface'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-8913454922455505982</id><published>2009-04-01T20:55:00.000+02:00</published><updated>2009-04-02T08:20:44.109+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><title type='text'>Note about performance in drizzle-jdbc</title><content type='html'>Ok, i don't really like to optimize early, but this made me learn using blocking queues and executor services. This blog post is very unscientific and does not provide any raw numbers, you can fetch them yourselves, look at the &lt;a href="http://bazaar.launchpad.net/%7Ekrummas/drizzle-jdbc/trunk/annotate/head:/src/test/java/org/drizzle/jdbc//LoadTest.java"&gt;LoadTest&lt;/a&gt; test case in &lt;a href="http://launchpad.net/drizzle-jdbc"&gt;drizzle-jdbc&lt;/a&gt;. The MySQL stuff is commented out since I want the tests to pass in &lt;a href="http://marcus.no-ip.biz/hudson/"&gt;hudson&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First, I ran a few comparisons between drizzle-jdbc against drizzle and Connector/J on MySQL, using the same test case, insert 1000 rows, read them back 1000 times. Connector/J was 5-10 times faster, then i remembered that tables in mysql have myisam as the default storage engine (doh). So, when i created the tables with InnoDB, the performance was still alot better with connector/j, but the difference was not as big (C/J was approx 50% faster). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The first optimization i did was to start fetching packets (communication between drizzle and client is done using packets, for example row packets, ok packets, error packets etc) in a background thread and putting them on a &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html"&gt;BlockingQueue&lt;/a&gt;. To manage the background thread I use an &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html"&gt;ExecutorService&lt;/a&gt;. So, whenever a packet is available on the stream, it is read back and put on the queue. The packet is a raw packet, i.e. the executor simply reads up length and stores the raw bytes in a "RawPacket" on the queue. The gain from this is that while the protocol figures out  what kind of packet it is, the next packet is prepared on the queue. Look here for the code of the &lt;a href="http://bazaar.launchpad.net/%7Ekrummas/drizzle-jdbc/trunk/annotate/head:/src/main/java/org/drizzle/jdbc/internal/packet//AsyncPacketFetcher.java"&gt;AsyncPacketFetcher. &lt;/a&gt;I also built a &lt;a href="http://bazaar.launchpad.net/%7Ekrummas/drizzle-jdbc/trunk/annotate/head:/src/main/java/org/drizzle/jdbc/internal/packet//SyncPacketFetcher.java"&gt;SyncPacketFetcher&lt;/a&gt; which does not use a background thread or queue, it simply creates the RawPackets directly when called.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;By pushing the packet fetching to a background thread, another natural optimization would be to return the result set from the protocol with a reference to the packet fetcher before starting to read RowPackets, and only consume the queue when the user of drizzle-jdbc wants to read a row. Then the user could start processing result sets before all rows are read back from the server.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The second optimization was to start prefetching data when it is available on the inputstream. I.e. read as much as possible whenever reading, and use the local buffered bytes when read():ing. A similar technique is used in connector/j. Look &lt;a href="http://bazaar.launchpad.net/%7Ekrummas/drizzle-jdbc/trunk/annotate/49?file_id=readaheadinputstream-20090401085820-1hb1v2agtwchslc5-2"&gt;here&lt;/a&gt; for the code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All in all, these optimizations take drizzle-jdbc close to the performance of connector/j (not all the way though, something like 5-10% off). But I want to stay away from any more optimizing until the &lt;a href="http://bazaar.launchpad.net/%7Eeday/libdrizzle/trunk/annotate/head:/PROTOCOL"&gt;new protocol&lt;/a&gt; is implemented in drizzle. It is also likely that my configuration of my local drizzled is not as good as the configuration of the mysql server I use. All these changes takes the design of drizzle-jdbc closer to what I want when the async stuff is available in drizzle.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-8913454922455505982?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/8913454922455505982/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=8913454922455505982' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8913454922455505982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8913454922455505982'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/04/note-about-performance-in-drizzle-jdbc.html' title='Note about performance in drizzle-jdbc'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-6754514899707413893</id><published>2009-03-21T14:15:00.000+01:00</published><updated>2009-03-21T14:25:29.180+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><title type='text'>Using EnumSet when communicating over the network</title><content type='html'>Many applications use bitmasks to send flags over the wire since it is a very efficient way of representing settings etc, problem is that the code to handle them is quite hard to read and maintain, on both the server and client side. To overcome this, EnumSet in Java can be used. If the flags that are masked in the value sent are represented as enums, the bitmask value can be seen as a set of enums, this concept is used in &lt;a href="http://launchpad.net/drizzle-jdbc/"&gt;drizzle-jdbc.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For example, to represent server capabilities the following enum is used:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;pre&gt;public enum ServerCapabilities {&lt;br /&gt;   LONG_PASSWORD((short)1),       /* new more secure passwords */&lt;br /&gt;   FOUND_ROWS((short)2),       /* Found instead of affected rows */&lt;br /&gt;   LONG_FLAG((short)4),       /* Get all column flags */&lt;br /&gt;   CONNECT_WITH_DB((short)8),       /* One can specify db on connect */&lt;br /&gt;   NO_SCHEMA((short)16),      /* Don't allow database.table.column */&lt;br /&gt;   COMPRESS((short)32),      /* Can use compression protocol */&lt;br /&gt;   ODBC((short)64),      /* Odbc client */&lt;br /&gt;   LOCAL_FILES((short)128),     /* Can use LOAD DATA LOCAL */&lt;br /&gt;   IGNORE_SPACE((short)256),     /* Ignore spaces before '(' */&lt;br /&gt;   CLIENT_PROTOCOL_41((short)512),     /* New 4.1 protocol */&lt;br /&gt;   INTERACTIVE((short)1024),    /* This is an interactive client */&lt;br /&gt;   SSL((short)2048),    /* Switch to SSL after handshake */&lt;br /&gt;   IGNORE_SIGPIPE((short)4096),    /* IGNORE sigpipes */&lt;br /&gt;   TRANSACTIONS((short)8192),    /* Client knows about transactions */&lt;br /&gt;   RESERVED((short)16384),   /* Old flag for 4.1 protocol  */&lt;br /&gt;   SECURE_CONNECTION((short)32768),  /* New 4.1 authentication */&lt;br /&gt;...&lt;br /&gt;   private final short bitmapFlag; //holds the value&lt;br /&gt;   ServerCapabilities(short i) {&lt;br /&gt;       this.bitmapFlag = i;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public static short fromSet(Set&amp;lt;ServerCapabilities&amp;gt; capabilities) {&lt;br /&gt;       short retVal = 0;&lt;br /&gt;       for(ServerCapabilities cap : capabilities) {&lt;br /&gt;           retVal = (short) (retVal | cap.getBitmapFlag());&lt;br /&gt;       }&lt;br /&gt;       return retVal;&lt;br /&gt;   }&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;   public static Set&amp;lt;ServerCapabilities&amp;gt; getServerCapabilitiesSet(short i) {&lt;br /&gt;       Set&amp;lt;ServerCapabilities&amp;gt; statusSet = EnumSet.noneOf(ServerCapabilities.class);&lt;br /&gt;       for(ServerCapabilities value : ServerCapabilities.values())&lt;br /&gt;           if((i &amp;amp; value.getBitmapFlag()) == value.getBitmapFlag())&lt;br /&gt;               statusSet.add(value);&lt;br /&gt;       return statusSet;&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This enum contains all capabilities of the drizzle server we are talking to. The value in the enum constructor is the bit position in the the value sent over the network. So, two convenience methods are implemented in the enum, one for taking the actual bit-masked value and creating an enum set, and one for taking an enum set and creating a bitmasked value. &lt;code&gt;fromSet&lt;/code&gt; creates a short which contains the flags set, and &lt;code&gt;getServerCapabilitiesSet&lt;/code&gt; creates an EnumSet which contains the enums represented by i.&lt;br /&gt;&lt;br /&gt;Now it is possible to handle bitmasked values like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;pre&gt;    short bitmask = readShortFromNetwork(); // yeah not really, but hey&lt;br /&gt; Set&amp;lt;ServerCapabilities&amp;gt; serverCapabilities = ServerCapabilities.getServerCapabilitiesSet(bitmask);&lt;br /&gt; if(serverCapabilities.containsAll(EnumSet.of(ServerCapabilities.TRANSACTIONS, ServerCapabilities.SSL)) {&lt;br /&gt;     doSomethingSecure();&lt;br /&gt; }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Also, when sending something to the server:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;pre&gt;&lt;br /&gt; Set&amp;lt;ServerCapabilities&amp;gt; capabilities = EnumSet.of(ServerCapabilities.TRANSACTIONS, ServerCapabilities.SSL);&lt;br /&gt; writeShortToNetwork(ServerCapabilities.fromSet(capabilities));&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So, what we've got is a type safe way of sending/receiving flags to/from a server. Internally, the enum set is stored in a long, so performance-wise it is close to equivalent of handling the bit-operations yourself.&lt;br /&gt;&lt;br /&gt;Look at these files for usage examples:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bazaar.launchpad.net/%7Ekrummas/drizzle-jdbc/trunk/annotate/head%3A/src/main/java/org/drizzle/jdbc/internal//DrizzleProtocol.java"&gt;DrizzleProtocol.java&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bazaar.launchpad.net/%7Ekrummas/drizzle-jdbc/trunk/annotate/head%3A/src/main/java/org/drizzle/jdbc/internal//ServerCapabilities.java"&gt;ServerCapabilities.java&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-6754514899707413893?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/6754514899707413893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=6754514899707413893' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/6754514899707413893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/6754514899707413893'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/03/using-enumset-when-communicating-over.html' title='Using EnumSet when communicating over the network'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-4359958227538201134</id><published>2009-03-19T21:32:00.000+01:00</published><updated>2009-03-19T22:11:11.903+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='drizzle-jdbc'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc'/><title type='text'>Introducing Drizzle JDBC</title><content type='html'>The last couple of months I've been working on a JDBC driver for &lt;a href="http://www.drizzle.org/"&gt;Drizzle&lt;/a&gt;, the driver is available &lt;a href="http://launchpad.net/drizzle-jdbc"&gt;here&lt;/a&gt;. The aim for the driver was to be lightweight and easy to develop. It is likely that Connector/J will support drizzle in the future, so the aim for this driver is to be a lightweight BSD-licensed alternative.&lt;br /&gt;&lt;br /&gt;To build the driver, do the following (java 6 is required):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ bzr branch lp:drizzle-jdbc&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ mvn compile&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you want to package the driver into something usable, you need to have a drizzle server on your localhost with a database called test_units_jdbc, then you can do:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ mvn package&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And you will get a .jar file in the target directory. There are also nightly builds available in &lt;a href="http://marcus.no-ip.biz/hudson/job/drizzle-jdbc/org.drizzle$drizzle-jdbc/"&gt;hudson&lt;/a&gt;&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The only current dependency is slf4j, so you need to put the api-jar and one of the implementations on the classpath, check &lt;a href="http://www.slf4j.org/"&gt;here&lt;/a&gt; for more help. The reason I use slf4j is that i don't want to impose a logging mechanism on the users, and I dont want to build something that scans the classpath for known logging implementations etc.&lt;br /&gt;&lt;br /&gt;Below is an example of how to use it:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Connection connection = DriverManager.getConnection("jdbc:drizzle://localhost:4427/test_units_jdbc");&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;Statement statement = connection.createStatement();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;statement.executeUpdate("INSERT INTO t1 (id) values (1)");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The connection string is on the form:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;jdbc:drizzle://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;host&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;database&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Notes about using this driver:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It is under heavy development and many features expected from a JDBC driver are not yet implemented. Of course, since it is very early in the development, there will be bugs!&lt;/li&gt;&lt;li&gt;Currently only Java6 is supported (JDBC4 was released with java6)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The internal protocols and API's will change when the new asynchronous server-API is available. This improve performance in the driver alot&lt;/li&gt;&lt;li&gt;Authentication is not supported, this is due to the fact that drizzle does not do this out-of-the-box and the way of doing the authentication is likely to change when the new protocol is in place&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The driver reads back the full result set into memory and there is currently no way of not doing this.&lt;/li&gt;&lt;li&gt;Prepared statements are&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It does work with hibernate and hibernate-jpa&lt;/li&gt;&lt;li&gt;It can be set up as a datasource in JBoss&lt;/li&gt;&lt;li&gt;It could, &lt;span style="font-weight: bold;"&gt;in theory&lt;/span&gt;, be used against MySQL as well&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Bug reports / feature requests are needed! Also, if anyone is interrested in contributing, please do so, contact me on IRC for example, freenode, #drizzle, my nick is marcuse&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-4359958227538201134?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/4359958227538201134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=4359958227538201134' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4359958227538201134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4359958227538201134'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2009/03/introducing-drizzle-jdbc.html' title='Introducing Drizzle JDBC'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-8560040725387459828</id><published>2008-12-12T13:16:00.000+01:00</published><updated>2008-12-12T13:25:34.738+01:00</updated><title type='text'>JAX-WS RI, JBoss and Guice</title><content type='html'>So, I needed to use the &lt;a href="https://jax-ws-commons.dev.java.net/guice/"&gt;guicemanaged&lt;/a&gt; annotation on some webservices at work, this was the way I got it working, if anyone has a better way, please let me know:&lt;br /&gt;&lt;div&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Download the jaxws-ri lib, unpack it&lt;/li&gt;&lt;li&gt;Download &lt;a href="http://google-guice.googlecode.com/"&gt;guice&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Download guicemanaged-0.2.jar&lt;/li&gt;&lt;li&gt;Copy the following libs to &lt;jboss&gt;/server/&lt;prolly&gt;/lib:&lt;ul&gt;&lt;li&gt;aopalliance.jar&lt;/li&gt;&lt;li&gt;guicemanaged-0.2.jar&lt;/li&gt;&lt;li&gt;guice-snapshot20081016.jar&lt;/li&gt;&lt;li&gt;jaxws-rt.jar&lt;/li&gt;&lt;li&gt;jaxb-xjc.jar&lt;/li&gt;&lt;li&gt;streambuffer.jar&lt;/li&gt;&lt;li&gt;stax-ex.jar&lt;/li&gt;&lt;/ul&gt;&lt;/prolly&gt;&lt;/jboss&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;This advice is probably good even if you don't need guice. When i copied all the jars from the jaxws RI package, jboss freaked out.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-8560040725387459828?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/8560040725387459828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=8560040725387459828' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8560040725387459828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8560040725387459828'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2008/12/jax-ws-ri-jboss-and-guice.html' title='JAX-WS RI, JBoss and Guice'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-8472247387648896927</id><published>2008-11-06T07:57:00.000+01:00</published><updated>2008-11-06T08:01:40.411+01:00</updated><title type='text'>Google Guice and JAX-WS RI revisited</title><content type='html'>&lt;div&gt;I've been coding a bit more with the guice-extension for jax-ws, and the result is actually quite nice, see below for how your web service endpoint would look when it is handled by guice:&lt;/div&gt;&lt;div&gt;&lt;code&gt;&lt;/code&gt;&lt;/div&gt;&lt;code&gt;&lt;div&gt;@GuiceManaged(module = WebServiceModule.class)&lt;/div&gt;&lt;div&gt;@WebService&lt;/div&gt;&lt;div&gt;public class AddNumbersImpl implements AddNumbers {&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;    private Calculator calculator;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;    @Inject&lt;/div&gt;&lt;div&gt;    public void setCalculator(Calculator calc)&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;        this.calculator=calc;&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;    @WebMethod&lt;/div&gt;&lt;div&gt;    public int addNumbers(int num1, int num2)&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;        return this.calculator.calc(num1,num2);&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/code&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;And WebServiceModule looks like this:&lt;/div&gt;&lt;div&gt;&lt;code&gt;&lt;/code&gt;&lt;/div&gt;&lt;code&gt;&lt;div&gt;public class WebServiceModule extends AbstractModule {&lt;/div&gt;&lt;div&gt;    protected void configure() {&lt;/div&gt;&lt;div&gt;        bind(Calculator.class).to(CalculatorImpl.class).in(Singleton.class);&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/code&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It can handle endpoints in any scope you want, if you want just one instance of the endpoint, you either annotate the class with @Singleton or bind it in Singleton scope in your module.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Head over to the &lt;a href="https://jax-ws-commons.dev.java.net/guice/"&gt;jax-ws commons project&lt;/a&gt; on dev.java.net to get the code, binaries and some information on how to use it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-8472247387648896927?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/8472247387648896927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=8472247387648896927' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8472247387648896927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/8472247387648896927'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2008/11/google-guice-and-jax-ws-ri-revisited.html' title='Google Guice and JAX-WS RI revisited'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6543848899761399219.post-4575200091097533269</id><published>2008-11-04T09:15:00.000+01:00</published><updated>2008-11-04T09:33:08.819+01:00</updated><title type='text'>Google Guice and jax-ws</title><content type='html'>&lt;div&gt;To integrate google guice with jax-ws, you need to use the InstanceResolver extension point. this way your endpoints will look like this;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;@GuiceManaged&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;@WebService(targetNamespace = "http://marcus", name="AddNumbers")&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;public class AddNumbersImpl {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;div&gt;  @Inject&lt;/div&gt;&lt;div&gt;  public void setCalculator(Calculator calc)&lt;/div&gt;&lt;div&gt;  {&lt;/div&gt;&lt;div&gt;      this.calculator=calc;&lt;/div&gt;&lt;div&gt;  }&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;To achieve this you need to create the annotation GuiceManaged;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;@Retention(RUNTIME)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;@Target(TYPE)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;@Documented&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;@WebServiceFeatureAnnotation(id=GuiceManagedFeature.ID, bean=GuiceManagedFeature.class)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;@InstanceResolverAnnotation(GuiceManagedInstanceResolver.class)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;public @interface GuiceManaged {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then you need to implement the GuiceManagedFeature:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;public class GuiceManagedFeature extends WebServiceFeature {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    public static final String ID="some_nice_id";&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    @FeatureConstructor&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    public GuiceManagedFeature()&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        this.enabled=true;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    public String getID() {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        return ID;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;And finally the actual InstanceResolver:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;public class GuiceManagedInstanceResolver&lt;t&gt; extends AbstractMultiInstanceResolver&lt;t&gt; {&lt;/t&gt;&lt;/t&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    private T instance=null;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    public GuiceManagedInstanceResolver(@NotNull Class&lt;t&gt; clazz)&lt;/t&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        super(clazz);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    public T resolve(@NotNull Packet packet) {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        if(instance==null)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;            instance=create();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;            Injector injector= Guice.createInjector(new WebServiceModule());&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;            injector.injectMembers(instance);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        return instance;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;That should do it, I'll update this post soon with a URL to the actual code (with documentation on how to use it. My plan is to make it more extensible (i.e. no hard dependency on the WebServiceModule) and possible to use in a non-singleton scope soon.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6543848899761399219-4575200091097533269?l=developian.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://developian.blogspot.com/feeds/4575200091097533269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6543848899761399219&amp;postID=4575200091097533269' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4575200091097533269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6543848899761399219/posts/default/4575200091097533269'/><link rel='alternate' type='text/html' href='http://developian.blogspot.com/2008/11/google-guice-and-jax-ws.html' title='Google Guice and jax-ws'/><author><name>Marcus Eriksson</name><uri>http://www.blogger.com/profile/13317356508042328314</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
