<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<feed xmlns="http://www.w3.org/2005/Atom">

	<title>Unofficial Erlang Planet</title>
	<link rel="self" href="http://www.erlangplanet.org/atom.xml"/>
	<link href="http://www.erlangplanet.org/"/>
	<id>http://www.erlangplanet.org/atom.xml</id>
	<updated>2010-07-30T06:15:56+00:00</updated>
	<generator uri="http://www.planetplanet.org/">Planet/2.0 +http://www.planetplanet.org</generator>

	<entry>
		<title type="html">Getting Your Open Source Project to 1.0</title>
		<link href="http://damienkatz.net/2010/07/getting_your_open_source_proje_1.html"/>
		<id>tag:damienkatz.net,2010://1.580</id>
		<updated>2010-07-29T18:55:56+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;The project I founded, Apache CouchDB, &lt;a href=&quot;http://www.nytimes.com/external/idg/2010/07/14/14idg-couchdb-nosql-database-ready-for-production-use-58614.html&quot;&gt;recently hit 1.0&lt;/a&gt;. I'm very proud :)&lt;/p&gt;

&lt;p&gt;It's been a long time, but we finally produced a release that's complete, performs well and is rock solid.&lt;/p&gt;

&lt;p&gt;Already CouchDB is on over 10 million machines. It's used by big respected websites (like the BBC) and groundbreaking organizations (Mozilla and Canonical). We run on most *nix, OS X, Windows, and even Android phones. Have dozens of frameworks and client libraries available. There are &lt;a href=&quot;http://couchdb.apache.org/docs/books.html&quot;&gt;2 books available&lt;/a&gt; for sale right now. There is a venture capital backed startup, &lt;a href=&quot;https://cloudant.com/&quot;&gt;Cloudant&lt;/a&gt;, that offers CouchDB hosting and scales to huge datasets. And I'm CEO of another venture backed ($2 million invested) 12 person start-up, &lt;a href=&quot;http://couch.io&quot;&gt;Couchio&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So how did I get here? It took a lot of time and effort (almost 5 years!), and the help of a lot of people. Here are some tips of what it took to get CouchDB to 1.0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Successful open source projects need a reason for being. You need to decide why you are creating a project and what problems it solves. Whether it's one or many reasons, you need to figure out what they are and explain them.&lt;/p&gt;

&lt;p&gt;Perhaps you are making something new, that hasn't existed. Why hasn't it existed it before? No had the idea? No one had the will to carry it through? Or maybe you are making something that's already in existence, like an HTTP server. What are your reasons? Simpler, faster, more features, different license?&lt;/p&gt;

&lt;p&gt;If you are just doing it as a learning exercise, that's fine. But don't expect to attract a community until you can explain why it's useful beyond you own personal goals.&lt;/p&gt;

&lt;p&gt;With CouchDB, my reasons were:&lt;br /&gt;
1. A schemaless document database with views, bi-directional replication and conflict detection to enable disconnected operation would be really useful.&lt;br /&gt;
2. I wanted to understand more about creating distributed systems and database internals.&lt;/p&gt;

&lt;p&gt;No one cares about reason #2 except for me. But the first reason is compelling.&lt;/p&gt;

&lt;p&gt;Make sure you can tell people why your project exists and what it's good for. And put the reasons on your project site where people can find them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Comes First&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't start a project unless you have a deep commitment to being a strong coder.&lt;/p&gt;

&lt;p&gt;Now I'm not saying you must be a strong coder to participate in a project. Not at all. I'm saying that you must be strong coder to lead one. Maybe you'll get lucky and somehow attract a some really good coders to your project. But most really good coders go to projects with already solid codebases, or start their own.&lt;/p&gt;

&lt;p&gt;Also, you don't have to be a strong coder when you start out, but you should know the basics and have a strong desire to learn and get better. Don't expect to attract anyone to your project until you have a substantial amount of working code that isn't a big ball of spaghetti.&lt;/p&gt;

&lt;p&gt;With CouchDB, I always emphasized the quality of the high-level design and code implementation. We cannot under any circumstances lose or corrupt your committed data, or get things into an inconsistent state. Reliability and durability are absolutely imperative. Any design or implementation that doesn't meet these goals doesn't make it into the project.&lt;/p&gt;

&lt;p&gt;Some projects might not have an emphasis on the reliability, but on absolute performance. That's a fine choice to make, but make sure your users know what they are trading off. And then actually deliver on the performance.&lt;/p&gt;

&lt;p&gt;As the project moves along, you will need to ensure the code quality (reliability, performance, resource, usage, etc) is improving over time. If you aren't a good coder, you won't be able to do this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Know What You Aren't&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Almost as important as knowing what your project is trying to accomplish, is know what it isn't trying to accomplish.&lt;/p&gt;

&lt;p&gt;When your project starts to get traction, but before it's done, you'll get a lot of people who want the project to work more like things they've used in the past. New users might think your goals and abilities are cool, but they'd trade it all for just a little more. They'll want everything your project does, plus a pony.&lt;/p&gt;

&lt;p&gt;The problem is feature and scope creep. Even if you are successfully keeping the project on track, the community may get slowed down dealing with people trying to make it something it's not. Stating clearly what your project isn't trying to do or be helps make it much easier to explain what you can't implement or change.&lt;/p&gt;

&lt;p&gt;Now, you can't define everything your project isn't. (It's not a video game. It's not accounting software. It's not a banana. It's not a rainbow. etc.). But you can find the things it's related to, overlaps with, or might be confused with, and explicitly say it's not those things.&lt;/p&gt;

&lt;p&gt;With CouchDB, because we are a database, people often asked us to add features that were in traditional RDBMS's, but didn't fit well with the CouchDB data model. Not being intimately familiar with CouchDB's model and how it all fits together, they don't realize that what they're asking for simply doesn't work. But because we explicitly stated on the project site we aren't a relational database and aren't trying to replace relational databases, it made it much easier to explain why those features weren't a good fit for what CouchDB is trying to accomplish.&lt;/p&gt;

&lt;p&gt;So if you don't clearly define what your project isn't, often people will try to make it into those things. This can damage the community, as moving forward is slower and people feel like they aren't being listened to. Be explicit what you aren't, and it makes it much easier to focus on what you actually are.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't Do Everything (Well)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So you are superstar coder, your code is clear and concise and high quality, you write clear complete documentation, your create all the tests, and you fix every bug. You are awesome!&lt;/p&gt;

&lt;p&gt;Thing is, you might be awesome, but until you actually get a community behind the project, the project will be limited in an absolute sense by what a single person can produce. And if you are doing everything, that's not a whole lot. Trying to do everything well means you'll probably never actually release anything.&lt;/p&gt;

&lt;p&gt;Unfortunately, at first, you _will_ need to do everything. But just don't do everything really well. Instead, you'll have do some things crappily, and then move on. In addition to writing all the code, you'll need to: Create a project site. Explain your project. Write documentation. Do the releases. Start a bug tracker. Create a mailing list and answer questions. And you'll have to do most of these things poorly if you want to keep moving the ball forward.&lt;/p&gt;

&lt;p&gt;You'll have to do some things poorly. But you'll need to pick a few things that you do really well and execute on those things. (The code should be one of the things you do well).&lt;/p&gt;

&lt;p&gt;And everything you do, you'll need to make it easy for others to participate. To add patches, to update and create documentation, make bug reports and send patches. And make it clear that help is desired.&lt;/p&gt;

&lt;p&gt;Don't get hung up on trying to make everything perfect. That just paralyzes you. But by picking a few things to do well, you will attract people to help you with the things you aren't doing well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Community Wants to Help&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open Source is awesome in the way it attracts people who just want to help make something cool. Many people want to contribute their time, but only if they think their help will amount to something in the long run. They don't want to spend time and effort on something that doesn't yet show potential or might be abandoned if the creators lose interest.&lt;/p&gt;

&lt;p&gt;If you have a solid codebase, then it becomes much easier to attract people to your community. If people can recognize there is at least something high quality about your project, but it's lacking in some areas, people will want to help you in those areas. But you have to have the high quality pieces in place. People don't want to be the one excellent contributor to dreck. They'd rather not have their efforts associated at all.&lt;/p&gt;

&lt;p&gt;They do want to be a part of something great. They want to add their work and make it even better. They want to contribute to projects where the total excellence of the project reflects well on them and their efforts. They want to make the world a better place, and don't want their efforts wasted.&lt;/p&gt;

&lt;p&gt;And people who like making the world a better place are exactly the kind of people you want to attract. You want people to have pride in their contributions, and to feel like they are really positively affecting the things they care about. Those people have lots of projects to choose where they can add their time and talents. If they feel their efforts on your project are wasted, they are gone. Make sure the people who show a strong desire to contribute aren't ignored, and feel like their efforts will eventually amount to something.&lt;/p&gt;

&lt;p&gt;Being a part of Apache has helped CouchDB tremendously. Partially it's because Apache has helped our visibility and credibility. But it's also because we've adopted the &quot;Apache Way&quot;, which is more focused on the community aspects of a project than on any specific contributor. Without our amazingly active community, CouchDB would be far behind where it is now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Community Is Often Incompetent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, many people who will want to help you will produce contributions of poor quality. You will have deal with this &quot;help&quot;, and do so diplomatically. The best way to point out the shortcomings with their contributions is to identify what needs improvement without denigrating their overall effort. This can be hard, and many don't want to hear why their efforts aren't up to the project's standards.&lt;/p&gt;

&lt;p&gt;Sometimes you have to hurt peoples feelings. But it's better to be honest then to have the quality of your project brought down. If they can't handle the feedback, so be it. The good news is the people who do listen to constructive criticism and actually improve the quality of their contributions are incredibly valuable. Look for these people and nurture their involvement.&lt;/p&gt;

&lt;p&gt;With CouchDB, we try to listen to all members of our community, but we only grant commit access to the ones who have shown high quality contributions. Our committers are our first line of defense against poor code and design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paul Graham Was Right&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It seems to make sense to choose a mainstream language for your project. The more mainstream it is, the larger the potential community you can attract. While that's true to an extent, the quality of the community is more important than its absolute size. Much more important.&lt;/p&gt;

&lt;p&gt;Using a mainstream language means you are also competing for contributor's time from other projects in the same language. So the pool is large, but in the end, you still have to attract quality developers from other things competing for their attention. And the competition might actually be stronger in that larger pool.&lt;/p&gt;

&lt;p&gt;The more mainstream a language, the more likely it is that a random developer knows it because it's what they use at work. They aren't necessarily interested in being more productive, being more reliable, or whatever. They are interested in getting paid, and they choose their language not for elegance, power or performance, but for the number of job openings available.&lt;/p&gt;

&lt;p&gt;If you pick a non-mainstream, more esoteric language, you tend to get a higher quality of developer. You tend to find people who absolutely love programming and building, and choose their languages not based on the scale of pay, but because they make the developers and projects more powerful. So while the total pool of contributors is smaller, they tend to give a higher quality of contribution. You get a much better signal to noise ratio.&lt;/p&gt;

&lt;p&gt;As Paul Graham explained in &lt;a href=&quot;http://www.paulgraham.com/avg.html&quot;&gt;Beating the Averages&lt;/a&gt;, the exotic languages tend to attract devs who love to learn and expand their toolbox. You'll attract more of the types of devs who don't mind creating new code to fill in the gaps, or diving into source to find a bug. They aren't afraid of what they don't know, they actually get excited by the chance to learn and do something new.&lt;/p&gt;

&lt;p&gt;But if you pick enterprisey language X, you might find you are spending more of your time fixing problems and dealing with developers who just don't &quot;get it&quot;. If you aren't careful, this can drown your project and bring the total code quality down to the point where you can't find good devs to help you anymore. With the less popular, esoteric languages, that tends to be less of a problem and you get a higher quality of contribution in general.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Your Brain&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I can keep listing all the stuff we did, but you aren't creating the same project under the same circumstances. Pretty much everything I've said here, we've &lt;em&gt;not&lt;/em&gt; followed at some point during the project. Often it was to the detriment of the project, but sometimes it just didn't make sense to blindly follow a rule or guideline.&lt;/p&gt;

&lt;p&gt;You have a brain, and using it is the most important thing to remember at anytime. Projects can't follow cookie cutter rules. Even the &quot;Apache Way&quot;, as I've discovered, means different things to different people, often at different times.&lt;/p&gt;

&lt;p&gt;So take my advice here with a grain of salt, and use your brain to figure out what's actually important to you, your project and it's community. Good luck!&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">CouchCamp is Coming Soon!</title>
		<link href="http://damienkatz.net/2010/07/couchcamp_is_coming_soon.html"/>
		<id>tag:damienkatz.net,2010://1.578</id>
		<updated>2010-07-26T17:10:07+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;&lt;span class=&quot;mt-enclosure mt-enclosure-image&quot;&gt;&lt;a href=&quot;http://www.couch.io/couchcamp&quot;&gt;&lt;img alt=&quot;713448945.png&quot; src=&quot;http://damienkatz.net/pics/713448945.png&quot; width=&quot;426&quot; height=&quot;200&quot; class=&quot;mt-image-none&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.couch.io/couchcamp&quot;&gt;CouchCamp, September 8-10&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the place to be to learn and hack on Apache CouchDB. In honor of the recent 1.0 release, for a limited time it's only &lt;em&gt;$500&lt;/em&gt;, with accommodations.&lt;/p&gt;

&lt;p&gt;In addition to unconference style discussions, we've got some great speakers:&lt;a href=&quot;http://twitter.com/selenamarie&quot;&gt; Selena Deckelman&lt;/a&gt;, &lt;a href=&quot;http://kryogenix.org/&quot;&gt;Stuart Langridge&lt;/a&gt;, &lt;a href=&quot;http://www.sauria.com/blog&quot;&gt;Ted Leung&lt;/a&gt;, &lt;a href=&quot;http://www.postgresql.org/community/contributors/&quot;&gt;Josh Berkus&lt;/a&gt;, &lt;a href=&quot;http://ajaxian.com/about-us&quot;&gt;Dion Almaer&lt;/a&gt; and me :)&lt;/p&gt;

&lt;p&gt;One thing I'm really excited to talk about is our work porting CouchDB to mobile platforms. Android, iOS, RIM, etc. We've got some very cool stuff coming :)&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Erlang and REST &amp;#8211; an interview with Steve Vinoski</title>
		<link href="http://erlanginside.com/erlang-and-rest-an-interview-with-steve-vinoski-185"/>
		<id>http://erlanginside.com/?p=185</id>
		<updated>2010-07-22T12:23:21+00:00</updated>
		<content type="html">Interview recorded at Erlang Factory, where Steve Vinoski discusses the key concepts of RPC frameworks such as CORBA, and how that compares to REST, and how Erlang fits into both worlds</content>
		<author>
			<name>Chad DePue</name>
			<uri>http://erlanginside.com</uri>
		</author>
		<source>
			<title type="html">Erlang Inside</title>
			<subtitle type="html">News and Information on Erlang and Concurrent Computing</subtitle>
			<link rel="self" href="http://erlanginside.com/feed/atom"/>
			<id>http://erlanginside.com/feed/atom</id>
			<updated>2010-07-22T13:31:03+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Zotonic rethinks the CMS with Erlang</title>
		<link href="http://erlanginside.com/zotonic-destroys-wordpress-and-rethinks-the-cms-with-erlang-149"/>
		<id>http://erlanginside.com/?p=149</id>
		<updated>2010-07-21T13:36:41+00:00</updated>
		<content type="html">A chat with Marc Worrell, Lead Architect of Zotonic - a new Content Management System written entirely in Erlang.</content>
		<author>
			<name>Chad DePue</name>
			<uri>http://erlanginside.com</uri>
		</author>
		<source>
			<title type="html">Erlang Inside</title>
			<subtitle type="html">News and Information on Erlang and Concurrent Computing</subtitle>
			<link rel="self" href="http://erlanginside.com/feed/atom"/>
			<id>http://erlanginside.com/feed/atom</id>
			<updated>2010-07-22T13:31:03+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Adding Health Checks to Deckard from Chef.</title>
		<link href="http://www.joeandmotorboat.com/2010/07/19/adding-health-checks-to-deckard-from-chef/"/>
		<id>http://www.joeandmotorboat.com/?p=1029</id>
		<updated>2010-07-19T20:52:09+00:00</updated>
		<content type="html">&lt;p&gt;Recently, we (at &lt;a href=&quot;https://cloudant.com/&quot;&gt;Cloudant&lt;/a&gt;) &lt;a href=&quot;http://www.joeandmotorboat.com/2010/06/04/just-opensourced-gaff-and-deckard/&quot;&gt;open sourced Deckard&lt;/a&gt;, a HTTP content check monitoring system based on CouchDB. One of the best bits about using Couch is that it gives you a ReST API and with Deckard it can be used to add new health checks. Doing a simple PUT adds new URLs to monitor. At &lt;a href=&quot;https://cloudant.com/&quot;&gt;Cloudant&lt;/a&gt; we love &lt;a href=&quot;http://www.opscode.com/&quot;&gt;Chef&lt;/a&gt; and use it for everything. Chef has things called resources and providers. &lt;a href=&quot;http://wiki.opscode.com/display/chef/Resources&quot;&gt;Resources&lt;/a&gt; are abstractions that describe the state you want a machine to be in. &lt;a href=&quot;http://wiki.opscode.com/display/chef/Providers&quot;&gt;Providers&lt;/a&gt; perform the actions described by a resource. A good example is using the &lt;a href=&quot;http://wiki.opscode.com/display/chef/Resources#Resources-Package&quot;&gt;package&lt;/a&gt; resource on Centos uses yum while on Ubuntu it uses apt-get. The resource abstracts that away, letting the provider (and node) deal with the specifics on how to install the package. This makes your recipes nice and DRY, use the same code to install packages on all sorts of platforms. There are resources and providers for anything from installing packages to even one I wrote for executing Erlang code via erl_call. One resource that works well with Deckard is the &lt;a href=&quot;http://wiki.opscode.com/display/chef/Resources#Resources-HTTPRequest&quot;&gt;HTTP request resource&lt;/a&gt;, using it makes it very easy to add health checks from your cookbooks. We use something like the following code to add checks to new nodes at Cloudant:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This code will add the document describing the check to the monitor_content_check database and then create a file so we can use &amp;#8220;not_if&amp;#8221; and Chef won&amp;#8217;t attempt to add the check twice. Pretty cool stuff and even more reason that everything should have an API. Even cooler than this example would be to use Chef Search to do the same thing but I&amp;#8217;ll save that for another blog post.&lt;/p&gt;</content>
		<author>
			<name>Joe's blog</name>
			<uri>http://www.joeandmotorboat.com</uri>
		</author>
		<source>
			<title type="html">Joe's Blog!</title>
			<link rel="self" href="http://www.joeandmotorboat.com/feed/"/>
			<id>http://www.joeandmotorboat.com/feed/</id>
			<updated>2010-07-30T06:15:19+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">New Column, New Interview</title>
		<link href="http://steve.vinoski.net/blog/2010/07/17/new-column-new-interview/"/>
		<id>http://steve.vinoski.net/blog/?p=610</id>
		<updated>2010-07-17T18:01:47+00:00</updated>
		<content type="html">&lt;p&gt;A couple newsworthy items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a href=&quot;http://steve.vinoski.net/pdf/IC-Getting_Started_with_Google_App_Engine_and_Clojure.pdf&quot;&gt;July/August 2010 issue&lt;/a&gt; (PDF) of &lt;a href=&quot;http://steve.vinoski.net/blog/internet-computing-columns/&quot;&gt;&lt;em&gt;The Functional Web&lt;/em&gt;&lt;/a&gt; column is available, this time with guest columnist &lt;a href=&quot;http://www.aaronbedra.com/&quot;&gt;Aaron Bedra&lt;/a&gt; writing about using &lt;a href=&quot;http://clojure.org/&quot;&gt;Clojure&lt;/a&gt; and the &lt;a href=&quot;http://compojure.org/&quot;&gt;Compojure web framework&lt;/a&gt; on the &lt;a href=&quot;http://code.google.com/appengine/&quot;&gt;Google App Engine&lt;/a&gt; platform. Pretty interesting read, and plenty of code examples.
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://sadekdrobi.com/&quot;&gt;Sadek Drobi&lt;/a&gt; interviewed me about Erlang and REST at &lt;a href=&quot;http://www.erlang-factory.com/&quot;&gt;Erlang Factory&lt;/a&gt; back in March, and the &lt;a href=&quot;http://www.infoq.com/interviews/steve-vinoski-erlang-rest&quot;&gt;interview is now up at InfoQ&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content>
		<author>
			<name>steve</name>
			<uri>http://steve.vinoski.net/blog</uri>
		</author>
		<source>
			<title type="html">Steve Vinoski's Blog</title>
			<subtitle type="html">Ask forgiveness, not permission.</subtitle>
			<link rel="self" href="http://steve.vinoski.net/blog/feed/atom/"/>
			<id>http://steve.vinoski.net/blog/feed/atom/</id>
			<updated>2010-07-17T18:15:19+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">PostgreSQL Erlang client library epgsql supports asynchronous messages from LISTEN/NOTIFY events</title>
		<link href="http://erlanginside.com/posgresql-client-epgsql-listen-notify-erlang-178"/>
		<id>http://erlanginside.com/?p=178</id>
		<updated>2010-07-08T19:27:05+00:00</updated>
		<content type="html">If you use PostgreSQL with Erlang, you're probably already familiar with the epgsql client library. Something that slipped my attention was the addition of...</content>
		<author>
			<name>Chad DePue</name>
			<uri>http://erlanginside.com</uri>
		</author>
		<source>
			<title type="html">Erlang Inside</title>
			<subtitle type="html">News and Information on Erlang and Concurrent Computing</subtitle>
			<link rel="self" href="http://erlanginside.com/feed/atom"/>
			<id>http://erlanginside.com/feed/atom</id>
			<updated>2010-07-22T13:31:03+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">ProcessOne releases OneCached, a Memcached in erlang</title>
		<link href="http://www.process-one.net/en/blogs/article/processone_releases_onecached_a_memcached_in_erlang/"/>
		<id>tag:process-one.net,2010:en/blogs/3.2892</id>
		<updated>2010-07-05T20:41:54+00:00</updated>
		<content type="html">&lt;p&gt;ProcessOne has just released OneCached, a Memcached server and client  implementation written in Erlang.&lt;/p&gt; &lt;p&gt;OneCached is a new Memcached server and client  implementation  written from scratch in Erlang by ProcessOne.&lt;/p&gt;
&lt;p&gt;From the &lt;a href=&quot;http://memcached.org/&quot;&gt;Memcached&lt;/a&gt; website:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What is Memcached?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Free &amp;amp; open source, high-performance, distributed memory object  caching system, generic in nature, but intended for use in speeding up  dynamic web applications by alleviating database load.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Memcached is an in-memory key-value store for small chunks of  arbitrary data (strings, objects) from results of database calls, API  calls, or page rendering.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Memcached is simple yet powerful. Its simple design promotes quick  deployment, ease of development, and solves many problems facing large  data caches. Its API is available for most popular languages.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;OneCached supports the set, add, replace, get, incr, decr, delete,  flush_all and quit commands. It doesn't handle expiration time.&lt;/p&gt;
&lt;p&gt;You call pull the source code from the public repository at: &lt;a href=&quot;https://git.process-one.net/onecached&quot;&gt;https://git.process-one.net/onecached&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre&gt;git clone git:&lt;span&gt;//git.process-one.net/onecached/mainline.git&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To compile, just run make, and to start, just type:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre&gt;bin/onecachedctl start&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;OneCached is released under the Erlang Public License (EPL), version  1.1. It is available from &lt;a href=&quot;http://www.process-one.net/en/labs/&quot;&gt;ProcessOne Labs&lt;/a&gt;.&lt;/p&gt;</content>
		<author>
			<name>Nicolas Vérité</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:07:05</id>
			<updated>2010-07-05T20:46:26+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">New Erlang job board &amp;#8211; totally-erlang.com</title>
		<link href="http://erlanginside.com/new-erlang-job-board-erlang-job-list-176"/>
		<id>http://erlanginside.com/?p=176</id>
		<updated>2010-07-05T11:27:25+00:00</updated>
		<content type="html">The Zotonic guys put together a new Erlang job board at http://totally-erlang.com/</content>
		<author>
			<name>Chad DePue</name>
			<uri>http://erlanginside.com</uri>
		</author>
		<source>
			<title type="html">Erlang Inside</title>
			<subtitle type="html">News and Information on Erlang and Concurrent Computing</subtitle>
			<link rel="self" href="http://erlanginside.com/feed/atom"/>
			<id>http://erlanginside.com/feed/atom</id>
			<updated>2010-07-22T13:31:03+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">erldocs.com updated with R14A support, mochiweb, and available for your own projects</title>
		<link href="http://erlanginside.com/erldocs-com-updated-with-r14a-support-mochiweb-and-available-for-your-own-projects-169"/>
		<id>http://erlanginside.com/?p=169</id>
		<updated>2010-06-29T12:53:43+00:00</updated>
		<content type="html">Dale Harvey just recently updated erldocs.com with R14A support. If you are doing any erlang development, or even looking to just learn a bit about erlang, I highly recommend using erldocs over the official documentation.</content>
		<author>
			<name>Chad DePue</name>
			<uri>http://erlanginside.com</uri>
		</author>
		<source>
			<title type="html">Erlang Inside</title>
			<subtitle type="html">News and Information on Erlang and Concurrent Computing</subtitle>
			<link rel="self" href="http://erlanginside.com/feed/atom"/>
			<id>http://erlanginside.com/feed/atom</id>
			<updated>2010-07-22T13:31:03+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">A Phase Shift for the ORM</title>
		<link href="http://debasishg.blogspot.com/2010/06/phase-shift-for-orm.html"/>
		<id>tag:blogger.com,1999:blog-22587889.post-8064504785804219074</id>
		<updated>2010-06-28T12:55:25+00:00</updated>
		<content type="html">I came to know about &lt;a href=&quot;http://github.com/delitescere/squealer&quot;&gt;Squealer&lt;/a&gt; from one of &lt;a href=&quot;http://twitter.com/deanwampler/status/17109490937&quot;&gt;Dean's tweets&lt;/a&gt; over the last weekend. Over there at the git repo README, there's a statement which makes a very succinct point on the role that relational mappers will be playing in the days to come. It says &quot;... ORMs had it the wrong way around: that the application should be persisting its data in a manner natural to it, and that external systems (like reporting and decision support systems - or even numbskull integration at the persistence layer) should bear the cost of mapping.&quot;&lt;br /&gt;&lt;br /&gt;I have expressed similar observations in the past, when I &lt;a href=&quot;http://debasishg.blogspot.com/2010/01/new-way-to-think-of-data-storage-for.html&quot;&gt;talked&lt;/a&gt; about the rationale of modeling data close to the way applications will be using them. I talk about this same architecture in an upcoming IEEE Software Multi-Paradigm Programming Special Issue for Sep/Oct 2010.&lt;br /&gt;&lt;br /&gt;In most of the applications that churn out domain models in an object oriented language and persist data in a relational store, we use the ORM layer as follows :&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/_r-NJO1NMiu4/TCgxam1RPiI/AAAAAAAAATM/HTY0BHZbxtI/s1600/data_hybrid_1_trans.gif&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;217&quot; src=&quot;http://2.bp.blogspot.com/_r-NJO1NMiu4/TCgxam1RPiI/AAAAAAAAATM/HTY0BHZbxtI/s400/data_hybrid_1_trans.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It sits between the domain model and the relational database, provides an isolation layer between the two at the expense of an intrusive framework invasion within an otherwise non-complicated application architecture.&lt;br /&gt;&lt;br /&gt;The scenario changes if we allow the application to manipulate and persist data in the same form that it uses for modeling its domain. My email application needs an address book as a composite object instead of being torn apart into multiple relational tables in the name of normalization. It will be better if I can program the domain model to access and persist all its entities in a document store that gives it the same flexibility. So the application layer does not have to deal with the translation between the two data models that adds a significant layer of complexity today. The normal online application flow doesn't need an ORM.&lt;br /&gt;&lt;br /&gt;How does the translation layer get shifted ?&lt;br /&gt;&lt;br /&gt;Consider an example application that uses &lt;a href=&quot;http://code.google.com/p/terrastore&quot;&gt;Terrastore&lt;/a&gt; as the persistent storage for implementing online domain functionalities. Terrastore is a document database having some similarities with each of CouchDB, MongoDB and Riak in the sense that data is stored in the form of JSON documents. However unlike others it has an emphasis on the &quot;C&quot; component of the &lt;a href=&quot;http://www.julianbrowne.com/article/viewer/brewers-cap-theorem&quot;&gt;CAP theorem&lt;/a&gt; and provides advanced scalability and elasticity features without sacrificing consistency. &lt;br /&gt;&lt;br /&gt;Terrastore is built on top of Terracotta, which is itself an ACID based object database that offers storage of data larger than your RAM size clustered across multiple machines. Terrastore uses the storage and clustering capabilities of Terracotta and adds more advanced features like partitioning, data manipulation and querying through client APIs.&lt;br /&gt;&lt;br /&gt;As long as you are using Terrastore as your persistent database for the domain model, your data layer is at the same level of abstraction as your domain layer. You manipulate objects in memory and store them in Terrastore in the same format. Terrastore, like all other NoSQL stores is schemaless and offers a collection based interface storing JSON documents. No impedance mismatch to handle so far between the application and the data model.&lt;br /&gt;&lt;br /&gt;Have a look at the following figure where there's no additional framework sitting between the application model and the data storage (Terrastore).&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/_r-NJO1NMiu4/TCgxl_WCWiI/AAAAAAAAATU/uUKDAfyrDiA/s1600/data_hybrid_2_trans.gif&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;163&quot; src=&quot;http://4.bp.blogspot.com/_r-NJO1NMiu4/TCgxl_WCWiI/AAAAAAAAATU/uUKDAfyrDiA/s400/data_hybrid_2_trans.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;However there are many reasons why you would like to have a relational database as an underlying store. Requirements like ad hoc reporting, building decision support systems or data warehouses are some of the areas which are best supported with relational engines or any of the extensions that relational vendors offer. Such applications are not real time and can very well be served out of a snapshot of data that has a temporal lag from the online version.&lt;br /&gt;&lt;br /&gt;Every NoSQL store and many SQL ones as well offer commit handlers for publishing async jobs. In Terrastore you can write custom event handlers that you can use to publish information from the document store to an underlying relational store. It's as simple as implementing the &lt;code&gt;terrastore.event.EventListener&lt;/code&gt; interface. This is well illustrated in the above figure. Translation to the relational model takes place here which is one level down the stack in your application architecture. The Terrastore event handlers are queued up in a synchronous FIFO manner while they execute asynchronously which is exactly what you need to scale out your application.&lt;br /&gt;&lt;br /&gt;I took up Terrastore just as an example - you can do most of the stuff (some of them differently) with other NoSQL stores as well front ending as the frontal persistent store of your application. In real life usage choose the store that best maps the need of your domain model. It can be a document store, it can be a generic key value store or a graph store.&lt;br /&gt;&lt;br /&gt;The example with which I started the post, &lt;a href=&quot;http://github.com/delitescere/squealer&quot;&gt;Squealer&lt;/a&gt;, provides a simple, declarative Ruby DSL for mapping values from document trees into relations. It was built to serve exactly the above use case with MongoDB as the frontal store of your application and MySQL providing the system of record as an underlying relational store. In this model also we see a shift of the translation layer from the main online application functionalities to a more downstream component of the application architecture stack. As the document says &quot;It can be used both in bulk operations on many documents (e.g. a periodic batch job) or executed for one document asynchronously as part of an after_save method (e.g. via a Resque job). It is possible that more work may done on this event-driven approach, perhaps in the form of a squealerd, to reduce latency&quot;. Nice!&lt;br /&gt;&lt;br /&gt;All the above examples go on to show us that the translation layer which has so long been existing between the core application domain logic and the persistent data model has undergone a phase shift. With many of today's NoSQL data stores allowing you to model your data closer to how the domain needs it, you can push away the translation further downstream. But again, you can only do this for some applications that fit this paradigm. With applications that need instant access to the relational store, this will not be a good fit. Use it whereever you deem it's applicable - besides the simplicity that you will get in your application level programming model, you can also scale your application more easily when you have a scalable frontal database along with non-blocking asynchronous writes shoveling data into the relational model.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/22587889-8064504785804219074?l=debasishg.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Debasish</name>
			<email>ghosh.debasish@gmail.com</email>
			<uri>http://debasishg.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Ruminations of a Programmer</title>
			<subtitle type="html">A programmer's blog - will deal with everything that relates to a programmer. Occasionally, it will contain some humour, some politics and some sport news.</subtitle>
			<link rel="self" href="http://debasishg.blogspot.com/feeds/posts/default?alt=rss"/>
			<id>tag:blogger.com,1999:blog-22587889</id>
			<updated>2010-07-22T07:00:03+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Spanish Language Erlang List</title>
		<link href="http://erlanginside.com/spanish-language-erlang-list-167"/>
		<id>http://erlanginside.com/?p=167</id>
		<updated>2010-06-25T01:53:35+00:00</updated>
		<content type="html">If you&amp;#8217;re looking for Spanish language group to discuss Erlang, Mariano Guerra recently started &amp;#8220;ErlAr&amp;#8220;, a mailing list for all things Erlang, but in Castellano. Mariano is the author of Efene, a Javascript-syntax language that compiles to Erlang bytecode. I&amp;#8217;m planning an interview with Mariano on Efene soon. There is a small but growing group [...]</content>
		<author>
			<name>Chad DePue</name>
			<uri>http://erlanginside.com</uri>
		</author>
		<source>
			<title type="html">Erlang Inside</title>
			<subtitle type="html">News and Information on Erlang and Concurrent Computing</subtitle>
			<link rel="self" href="http://erlanginside.com/feed/atom"/>
			<id>http://erlanginside.com/feed/atom</id>
			<updated>2010-07-22T13:31:03+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Case study: Arc International</title>
		<link href="http://www.process-one.net/en/blogs/article/case_study_arc_international/"/>
		<id>tag:process-one.net,2010:en/blogs/3.2881</id>
		<updated>2010-06-23T10:30:21+00:00</updated>
		<content type="html">&lt;p&gt;Arc International has migrated away from a proprietary solution to the open source, and open standards ejabberd and Psi, realising cost-savings and productivity increase.&lt;/p&gt; &lt;p&gt;Arc International is well known for distributing famous tableware brands such as Luminarc&amp;reg;, Arcoroc, Chef&amp;amp;Sommelier, Pyrex and Cristal d&amp;rsquo;Arques Paris. With 12,000 employees around the world, from Europe to Asia, and the Middle East to North America, they needed to lower the costs of their previous solutions.&lt;/p&gt;
&lt;p&gt;They have chosen ejabberd, as an open-source, scalable XMPP platform. In conjunction, with the Psi cllent Arc International has achive their goals of cost-savings and high-quality service.&lt;/p&gt;
&lt;p&gt;The cost-savings have benefitted from a lower TCP on IT, as well as reduced telephone bills, while providing a same feature-set to the employees worldwide.&lt;/p&gt;
&lt;p&gt;Read our &lt;a href=&quot;http://www.process-one.net/en/customers/case_studies/&quot;&gt;case study&lt;/a&gt; on the website, or &lt;a href=&quot;http://www.process-one.net/resources/case_studies/ProcessOne_Arc_Int_Case_Study.pdf&quot;&gt;as a PDF&lt;/a&gt; (582 KB).&lt;/p&gt;</content>
		<author>
			<name>Nicolas Vérité</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:07:05</id>
			<updated>2010-07-05T20:46:26+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry>
		<title type="html">Migrating From MySQL to CouchDB</title>
		<link href="http://damienkatz.net/2010/06/migrating_from_mysql_to_couchd.html"/>
		<id>tag:damienkatz.net,2010://1.576</id>
		<updated>2010-06-22T18:08:51+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;Here is a detailed white paper from John P. Woods of &lt;a href=&quot;http://www.interactivemediums.com/&quot;&gt;Interactive Mediums&lt;/a&gt;, going into depth about their migration of their mobile marketing archive from MySQL to CouchDB.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.couch.io/migrating-to-couchdb&quot;&gt;http://www.couch.io/migrating-to-couchdb&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">CouchCamp, aka BurningCouch!</title>
		<link href="http://damienkatz.net/2010/06/couchcamp_aka_burningcouch.html"/>
		<id>tag:damienkatz.net,2010://1.575</id>
		<updated>2010-06-22T17:12:57+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;&lt;span class=&quot;mt-enclosure mt-enclosure-image&quot;&gt;&lt;img alt=&quot;713448945.png&quot; src=&quot;http://damienkatz.net/pics/713448945.png&quot; width=&quot;426&quot; height=&quot;200&quot; class=&quot;mt-image-none&quot; /&gt;&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://couchcamp2010.eventbrite.com/&quot;&gt;Registration for CouchCamp&lt;/a&gt; is now open. &lt;a href=&quot;http://www.couch.io/couchcamp&quot;&gt;CouchCamp&lt;/a&gt; is our conference about CouchDB, September 8th - 10th 2010 at Walker Creek Ranch, north of the Bay area.&lt;/p&gt;

&lt;p&gt;This is the event to learn all about CouchDB and it's innards, the community, and how much beer I can drink before hurling. It's going to be fun!&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">How Software Is Built: Apache CouchDB</title>
		<link href="http://damienkatz.net/2010/06/how_software_is_built_apache_c.html"/>
		<id>tag:damienkatz.net,2010://1.574</id>
		<updated>2010-06-18T18:31:23+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;Here is a detailed interview I recently did for HowSoftwareIsBuilt.com about CouchDB, document databases, cloud and replication:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://howsoftwareisbuilt.com/2010/06/18/interview-with-damien-katz-apache-couchdb/&quot;&gt;http://howsoftwareisbuilt.com/2010/06/18/interview-with-damien-katz-apache-couchdb/&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Miscellaneous CouchDB News</title>
		<link href="http://damienkatz.net/2010/06/miscellaneous_couchdb_news.html"/>
		<id>tag:damienkatz.net,2010://1.572</id>
		<updated>2010-06-15T16:58:21+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;Awesome New Hires: We've recently hired &lt;a href=&quot;http://vmx.cx/&quot;&gt;Volker Mische&lt;/a&gt; of GeoCouch, and CouchDB contributor &lt;a href=&quot;http://fdmanana.wordpress.com/&quot;&gt;Filipe Manana&lt;/a&gt;. These guys are damn good!&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.couch.io/case-study-anologue&quot;&gt;CouchDB Case Study: Anologue&lt;/a&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;div&gt;&quot;It was difficult to continue programming at times, as I could hardly see through the tears of joy.&quot;&lt;p&gt;- Jon Adams, Chief Architect of Anologue &lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;CouchCamp: &lt;a href=&quot;http://www.couch.io/couchcamp&quot;&gt;September 8th - 10th 2010&lt;/a&gt; Registration will open soon.&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Just Opensourced: Gaff and Deckard</title>
		<link href="http://www.joeandmotorboat.com/2010/06/04/just-opensourced-gaff-and-deckard/"/>
		<id>http://www.joeandmotorboat.com/?p=1021</id>
		<updated>2010-06-04T21:18:50+00:00</updated>
		<content type="html">&lt;p&gt;&lt;em&gt;This post was stolen from my original post on the &lt;/em&gt;&lt;a href=&quot;http://blog.cloudant.com/just-opensourced-gaff-and-deckard&quot;&gt;&lt;em&gt;Cloudant blog&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Today we released two open source projects that have been in use internally at Cloudant for some time now, &lt;a href=&quot;http://github.com/joewilliams/gaff&quot;&gt;Gaff&lt;/a&gt; and &lt;a href=&quot;http://github.com/joewilliams/deckard&quot;&gt;Deckard&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All of our infrastructure is in the cloud and as such we need a way for disperate systems to all request resources, this is where Gaff comes in. Gaff is a pubsub daemon for asynchronously talking to cloud APIs using AMQP. Currently it supports a subset of the Dynect (DNS), Slicehost and EC2 APIs and uses &lt;a href=&quot;http://twitter.com/geemus&quot;&gt;geemus&lt;/a&gt;&amp;#8216; awesome &lt;a href=&quot;http://github.com/geemus/fog&quot;&gt;fog&lt;/a&gt; Ruby library. The basic workflow for Gaff is to send &lt;a href=&quot;http://json-rpc.org/&quot;&gt;JSON-RPC&lt;/a&gt; formated messages to an AMQP exchange with a routing key corresponding to the API you are talking to, you could be sending these messages from a web application or another service.  Each message gets routed to an API specific queue and is picked up by Gaff and turned into the appropriate API call, starting, stopping, modifying your servers on EC2 or elsewhere.&lt;/p&gt;
&lt;p&gt;We have a lot of CouchDB instances to keep tabs on to do this we wrote Deckard. Deckard is a HTTP check monitoring system based on CouchDB. Yo dawg! What better than to monitor CouchDB with CouchDB (and some Ruby)? Deckard supports basic HTTP content checks, email alerts, SMS alerts (via email) for on-call rotations, basic maintenance scheduling, replication latency alerts (between two Couches) and even has EC2 Elastic IP support for failover between two EC2 instances. Best of all since it&amp;#8217;s based on Couch you get an API for free, just PUT a doc in the HTTP checks database and you get a new HTTP check the next time Deckard runs.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Checkout these and my other projects on &lt;/em&gt;&lt;a href=&quot;http://github.com/joewilliams&quot;&gt;&lt;em&gt;GitHub&lt;/em&gt;&lt;/a&gt;&lt;em&gt; and follow &lt;/em&gt;&lt;a href=&quot;http://twitter.com/cloudant&quot;&gt;&lt;em&gt;Cloudant&lt;/em&gt;&lt;/a&gt;&lt;em&gt; and &lt;/em&gt;&lt;a href=&quot;http://twitter.com/williamsjoe&quot;&gt;&lt;em&gt;myself&lt;/em&gt;&lt;/a&gt;&lt;em&gt; on Twitter.&lt;/em&gt;&lt;/p&gt;</content>
		<author>
			<name>Joe's blog</name>
			<uri>http://www.joeandmotorboat.com</uri>
		</author>
		<source>
			<title type="html">Joe's Blog!</title>
			<link rel="self" href="http://www.joeandmotorboat.com/feed/"/>
			<id>http://www.joeandmotorboat.com/feed/</id>
			<updated>2010-07-30T06:15:19+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">ejabberd 2.1.4 and exmpp 0.9.4 bugfix releases</title>
		<link href="http://www.process-one.net/en/blogs/article/ejabberd_2.1.4_and_exmpp_0.9.4_bugfix_releases/"/>
		<id>tag:process-one.net,2010:en/blogs/3.2846</id>
		<updated>2010-06-04T11:22:42+00:00</updated>
		<content type="html">&lt;p&gt;We are pleased to announce the bugfix releases ejabberd 2.1.4 and exmpp 0.9.4.&lt;/p&gt; &lt;h2&gt;Regarding ejabberd 2.1.4:&lt;/h2&gt;
&lt;h3&gt;Brief summary of changes:&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bounce messages when closing c2s session&lt;/li&gt;
&lt;li&gt;Bugfixes when handling Service Discovery to contacts&lt;/li&gt;
&lt;li&gt;Don't send error stanza as reply to error stanza&lt;/li&gt;
&lt;li&gt;Don't store blocked messages in offline queue&lt;/li&gt;
&lt;li&gt;Extauth: Optionally cache extauth users in mnesia&lt;/li&gt;
&lt;li&gt;Full support for XEP-0115 Entity Capabilities v1.5&lt;/li&gt;
&lt;li&gt;HTTP-Bind: Remove 100ms delay, export functions for prebinding methods&lt;/li&gt;
&lt;li&gt;LDAP: Inband password change, Extensible match support, and ldap_tls_verify&lt;/li&gt;
&lt;li&gt;Localization: Updated most translations&lt;/li&gt;
&lt;li&gt;MUC: Refactor code to reduce calls to get_affiliation and get_role&lt;/li&gt;
&lt;li&gt;ODBC: Add created_at column also to PostgreSQL schema&lt;/li&gt;
&lt;li&gt;PAM: New option pam_userinfotype to provide username or JID&lt;/li&gt;
&lt;li&gt;Pubsub: Send node notification. Enforce presence_based_delivery, show_values&lt;/li&gt;
&lt;li&gt;Vcard: Automatic vcard avatar addition in presence&lt;/li&gt;
&lt;li&gt;WebAdmin: New Access rule webadmin_view for read-only&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Check the Release Notes for a more complete list of changes:&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://www.process-one.net/en/ejabberd/release_notes/release_note_ejabberd_2.1.4&quot;&gt;http://www.process-one.net/en/ejabberd/release_notes/release_note_ejabberd_2.1.4&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you upgrade from ejabberd 2.0.5 or older, read carefully the release notes of ejabberd 2.1.0 too, because there were several changes in the installation path and the configuration options.&lt;br /&gt;&lt;br /&gt;The list of solved tickets since previous version is available on ProcessOne bug tracker:&lt;br /&gt;&lt;a href=&quot;http://redir.process-one.net/ejabberd-2.1.4&quot;&gt;http://redir.process-one.net/ejabberd-2.1.4&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;ejabberd 2.1.4 is available as source code package and binary installers for Linux 32 bits, 64 bits, Mac OS X Intel, and Windows:&lt;br /&gt;&lt;a href=&quot;http://www.process-one.net/en/ejabberd/downloads&quot;&gt;http://www.process-one.net/en/ejabberd/downloads&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;Regarding exmpp 0.9.4:&lt;/h2&gt;
&lt;h3&gt;Brief summary of changes:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add unexpected-request with cancel needed by pubsub&lt;/li&gt;
&lt;li&gt;Caps: Add exmpp_caps to the compilation scripts&lt;/li&gt;
&lt;li&gt;Caps: Move Caps erlang records to a header file&lt;/li&gt;
&lt;li&gt;Handle the case that the payload is incorrectly defined in error stanzas&lt;/li&gt;
&lt;li&gt;Preliminary documentation of functions from ejabberd 2 available in exmpp&lt;/li&gt;
&lt;li&gt;Remove unexpected-request with cancel as this is pubsub specific&lt;/li&gt;
&lt;li&gt;Support for SRV DNS query&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;exmpp home page:&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://support.process-one.net/doc/display/EXMPP/&quot;&gt;http://support.process-one.net/doc/display/EXMPP/&lt;/a&gt;&lt;br /&gt;or easier to remember: &lt;a href=&quot;http://exmpp.org/&quot;&gt;http://exmpp.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;Download exmpp 0.9.4 source code package from:&lt;a href=&quot;http://download.process-one.net/exmpp/&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://download.process-one.net/exmpp/&quot;&gt;http://download.process-one.net/exmpp/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can also check the ProcessOne Labs page:&lt;br /&gt;&lt;a href=&quot;http://www.process-one.net/en/labs/&quot;&gt;http://www.process-one.net/en/labs/&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>Jérôme Sautret</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:07:05</id>
			<updated>2010-07-05T20:46:26+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry>
		<title type="html">CouchDB on your TV</title>
		<link href="http://damienkatz.net/2010/06/couchdb_on_your_tv.html"/>
		<id>tag:damienkatz.net,2010://1.571</id>
		<updated>2010-06-04T00:53:54+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;After &lt;a href=&quot;http://damienkatz.net/2010/05/google_denies_our_commercial.html&quot;&gt;initially getting rejected for sound issues&lt;/a&gt;, Google Ads has finally approved our awesome Couchio commercial.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://vimeo.com/12280699&quot;&gt;GoogleAds Commercial Version&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we've aired this commercial 11 times so far, 5 times during Robot Chicken, twice duringAqua Teen Hunger Force, once during Tim and Eric's Awesome Show, Great Job! and 3 times on VH1.&lt;/p&gt;

&lt;p&gt;It has gone to a total of 321,253 impressions, which means 321,253 people have seen Chris running like a lunatic around the streets of Oakland, singing the CouchDB praises.&lt;/p&gt;

&lt;p&gt;This has cost us a total of $709.57!&lt;/p&gt;

&lt;blockquote&gt;&lt;div&gt;Just saw a commercial for CouchDB. Seriously. I'm at a loss for words. #couchdb #couchio&lt;p&gt;&lt;a href=&quot;http://twitter.com/jrgarcia/statuses/15244999117&quot;&gt;@jrgarcia&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;Someday CouchDB will actually be inside your TV, you can watch CouchDB while watching your CouchDB TV from your couch.Yo dawg.&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Grokking Functional Data Structures</title>
		<link href="http://debasishg.blogspot.com/2010/05/grokking-functional-data-structures.html"/>
		<id>tag:blogger.com,1999:blog-22587889.post-4995001879225534200</id>
		<updated>2010-05-31T12:20:46+00:00</updated>
		<content type="html">&lt;div class=&quot;separator&quot;&gt;&lt;/div&gt;&lt;a href=&quot;http://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504?ie=UTF8&amp;tag=ruminationso-20&amp;link_code=bil&amp;camp=213689&amp;creative=392969&quot; target=&quot;_blank&quot;&gt;&lt;img alt=&quot;Purely Functional Data Structures&quot; src=&quot;http://ws.amazon.com/widgets/q?MarketPlace=US&amp;ServiceVersion=20070822&amp;ID=AsinImage&amp;WS=1&amp;Format=_SL160_&amp;ASIN=0521663504&amp;tag=ruminationso-20&quot; /&gt;&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=ruminationso-20&amp;l=bil&amp;camp=213689&amp;creative=392969&amp;o=1&amp;a=0521663504&quot; width=&quot;1&quot; /&gt;With so many languages espousing functional programming paradigms, it's no wonder that functional implementations of common data structures are also becoming more and more popular. As a programmer it's important that we learn to adopt them into our repertoire of tools and techniques.&lt;br /&gt;&lt;br /&gt;Imperative data structures operate through in-place mutation of data. In our everyday usage of data structures in Java we mutate lists, arrays and any other type to realize the algorithm that we implement. Most of the books on data structures and algorithms explain all the complexity analyses of them using imperative data structures as case studies. When we create an object in Java (an instance of an abstract data type) and invoke some methods on it (some of which can potentially mutate its state) we get some result as an observable outcome of the sequence of operations. This sequence of operations on the value of the abstract data type constitutes a &lt;i&gt;logical future&lt;/i&gt; of that type.&lt;br /&gt;&lt;br /&gt;With functional data structures, immutability is the buzz of the day, though it's not mandatory that all of them have to be immutable. Many functional languages allow mutable data structures, which, more often than not have also proved to be more pragmatic than the pure school of thought. I wrote a &lt;a href=&quot;http://debasishg.blogspot.com/2010/01/pragmatics-of-impurity.html&quot;&gt;blog post&lt;/a&gt; on this same topic some time back. &lt;br /&gt;&lt;br /&gt;The other point of view that purists say is that the main point is not that whether you need a mutable array or a hash table. The more important part is that you need to access or update a data structure within a certain bound of time and space complexity. Okasaki's book &lt;a href=&quot;http://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504&quot;&gt;Purely Functional Data Structures&lt;/a&gt; contains a rich collection of functional implementations of many of the popular imperative data structures. And quite contrary to what we tend to believe, given proper language support, these implementations are often as efficient as their imperative counterparts.&lt;br /&gt;&lt;br /&gt;When we talk about functional programming, we talk about immutability of data structures and purity of functions. In the absence of mutable state, these are the two cornerstones that make reasoning of concurrent programs much easier in the functional paradigm. Since data structures are immutable, there's no in-place update of values, which means that every operation that changes the value of a data structure will create a new instance of it. So at the end of n operations on an instance of an ADT we will have all the previous versions of the data structure available for access. This is called &lt;i&gt;persistence&lt;/i&gt; of data structures, unlike the imperative ones that we discussed earlier, where one update destroys its previous state (we call them &lt;i&gt;ephemeral&lt;/i&gt; data structures). Unlike ephemeral data structures which has a single logical future (as we saw earlier), persistent data structures can potentially have multiple logical futures. &lt;br /&gt;&lt;br /&gt;Have a look at the following figure, where the list &lt;code&gt;l&lt;/code&gt; can have 2 logical futures based on the two possible mutating operations that we make on it. None of them mutate the original list and at the end we still have &lt;code&gt;l&lt;/code&gt; as &lt;code&gt;'(1 2 3)&lt;/code&gt;. Only the two logical futures point to two different instances of the ADT.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/_r-NJO1NMiu4/TAM7zFcmyYI/AAAAAAAAAOw/FlJaOyNzXFk/s1600/ds_1_new.gif&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/_r-NJO1NMiu4/TAM7zFcmyYI/AAAAAAAAAOw/FlJaOyNzXFk/s320/ds_1_new.gif&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Since Clojure sequences are persistent, we have all instances of the ADT accessible even after the entire sequence of operations. Had persistence meant brutal copying of instances, obviously we would not have the same performance guarantees as the imperative ones. Persistent data structures are implemented through careful sharing of structures across instances that make them affordable in real life applications. Have a look at the following tree structure that employs copying of paths from the root down to the newly inserted leaf while sharing the rest with the original ADT.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/_r-NJO1NMiu4/TAM8LdJGRqI/AAAAAAAAAO4/q-Ql4v0FAD4/s1600/ds_2_new.gif&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://1.bp.blogspot.com/_r-NJO1NMiu4/TAM8LdJGRqI/AAAAAAAAAO4/q-Ql4v0FAD4/s320/ds_2_new.gif&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As with the earlier scenario, both the versions of the tree are available even after adding the new node &lt;code&gt;8&lt;/code&gt; to the tree - &lt;code&gt;xs&lt;/code&gt; points to the original tree, while &lt;code&gt;ys&lt;/code&gt; points to the new one.&lt;br /&gt;&lt;br /&gt;Despite the fact that functional data structures are persistent, it's possible that their implementations make use of mutable storage. It's mostly done for efficiency of implementation, as we have seen with transients in Clojure. However, for all practical purposes, the data structure is published to its clients as an immutable one. &lt;br /&gt;&lt;br /&gt;It's also possible that we can implement a persistent data structure using an imperative language like Java. In fact, &lt;a href=&quot;http://functionaljava.org/&quot;&gt;FunctionalJava&lt;/a&gt; does exactly the same and offers a rich suite of persistent data structures developed in Java. But of course there's a trade-off. First, the usage looks intimidating with Java being quite verbose and without much of type-inferencing capabilities. And, as Okasaki points out in his book, you need to have an implementation of call-by-need in order to have improved amortized complexity of functional data structures. That's the subject of another post, some other day.&lt;br /&gt;&lt;br /&gt;What would be a life like without mutable arrays and hash-tables, the bread and butter data structures on which imperative programming thrives upon?&lt;br /&gt;&lt;br /&gt;Well, in functional languages lists, trees and tuples take the place of arrays and hash-tables. The basic unit of a functional data structure is to find a general representation of a sequence. And then apply recursive transformations on it to implement specific operations. In this post I give you a very brief look at a couple of such building blocks that are used extensively to implement persistent data structures in many languages.&lt;br /&gt;&lt;br /&gt;Consider the use case for a data structure where you would like to reach a specific item (often called a focus point) within the structure and do manipulations around it. With mutable structures you can reach a specific node within a list, an array or a tree and make changes to it. Or the very sole reason for which doubly linked lists exist is to allow you to reach a node within the list and move in either direction. Or you may want to have a new node and splice it within an existing doubly linked list using a minimum number of pointer manipulations.&lt;br /&gt;&lt;br /&gt;In the functional world we have zippers which can be adapted to this very use case. &lt;a href=&quot;http://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf&quot;&gt;Zipper&lt;/a&gt;, invented by Gerard Huet, is a generic data structure which allows you to identify a focal point within an ADT and make all manipulations around it as cheap as in-place updates. And it does all this in a completely immutable and persistent way. Every focal point within the tree is identified by a pair of Tree and Context, each of which is again a recursive data structure. The root of the Tree is the focal point around which we would like to do mutable operations. The functional pearl paper by Huet has all the details of this functional data structure. Clojure has a nice implementation of &lt;a href=&quot;http://github.com/richhickey/clojure/blob/master/src/clj/clojure/zip.clj&quot;&gt;zipper&lt;/a&gt; as part of its core distribution. Zipper is a general purpose data structure and has lots of exciting use cases. I hope to cover some of them in my upcoming posts.&lt;br /&gt;&lt;br /&gt;Another interesting data structure used functionally is the &lt;a href=&quot;http://www.soi.city.ac.uk/~ross/papers/FingerTree.html&quot;&gt;finger tree&lt;/a&gt;, invented by Hinze and Paterson. A finger tree is a 2-3 tree representation of a sequence that gives you cheap access to 'fingers', where you would like to do your manipulations on. And then you can define transformation functions using reductions and monoids that implement specific operations. For example, you can annotate every node of a finger tree using a characteristic function (modeled as a monoid), which you can use to look up specific elements having that property. If you want to implement fast positional operations (like accessing the nth element of the sequence), annotate the finger tree with the 'size' function, so that every node has the size of the subtree stored as its measure. Given size annotations we can now find the nth element in O(log n) time. Similarly annotating the tree with a 'priority' function turns a finger tree into a priority queue. Similarly you can implement deques, interval trees and a host of other data structure variants using the single underlying representation.&lt;br /&gt;&lt;br /&gt;This post is just an introduction to functional data structures and I hope to cover some of the specific ones in future. The key difference in implementation with mutable data structures is that the functional ones are based on recursive transformations, easier to model using the power of pure functions. They are persistent and as we discussed above can have multiple logical futures. This makes their runtime analyses a big challenge. In order to obtain amortized complexity that match their mutable counterparts you need to have support for laziness and &lt;a href=&quot;http://homepages.inf.ed.ac.uk/stg/NOTES/node72.html&quot;&gt;call-by-need&lt;/a&gt; from the underlying implementation language. Computations once forced need to be memoized so that the next logical future can use it without any additional expense on its realized cost of execution.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/22587889-4995001879225534200?l=debasishg.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Debasish</name>
			<email>ghosh.debasish@gmail.com</email>
			<uri>http://debasishg.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Ruminations of a Programmer</title>
			<subtitle type="html">A programmer's blog - will deal with everything that relates to a programmer. Occasionally, it will contain some humour, some politics and some sport news.</subtitle>
			<link rel="self" href="http://debasishg.blogspot.com/feeds/posts/default?alt=rss"/>
			<id>tag:blogger.com,1999:blog-22587889</id>
			<updated>2010-07-22T07:00:03+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">High Performance CouchDB</title>
		<link href="http://damienkatz.net/2010/05/high_performance_couchdb.html"/>
		<id>tag:damienkatz.net,2010://1.570</id>
		<updated>2010-05-25T18:47:06+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;At Couchio we are working with a company that makes high performance database appliances. These are complete system stacks where all the components, software and interconnects are carefully chosen, modified and optimized. They can deliver performance and scalability that's often an order of magnitude better than what can be accomplished by assembling your own systems with commodity components, and reducing overall hardware and admin costs.&lt;/p&gt;

&lt;p&gt;So if you are a user of Apache CouchDB and are interested in high performance CouchDB servers, we'd love to talk with you to help us shape our plans and offerings, and potentially join an early adopters program. Email me at damien@couch.io.&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Adding support for more than 1024 files to etorrent.</title>
		<link href="http://jlouisramblings.blogspot.com/2010/05/adding-support-for-more-than-1024-files.html"/>
		<id>tag:blogger.com,1999:blog-5411139659011156551.post-9098078301257594636</id>
		<updated>2010-05-23T07:15:23+00:00</updated>
		<content type="html">Some torrent files contain a humongous amount of files. Thousands. This is one of the problems you have to cope with as a client-writer and I plan to take care of both etorrent and combinatorrent. However, the solution I've adopted for etorrent is sinisterly beautiful, so I decided to write it down.&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;The Problem&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;Open files are limited on UNIX systems. This is to protect different applications against each other and to circumvent an eventual resource exhaustion on the system. A typical limit is 1024 files, or fewer in some cases. In etorrent, a file is governed by a process which plays the role of that file. Whenever you want to do a file operation on that file, you get hold of the process Pid and send it a message. Simple.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;Resources are limited by a timeout in these file processes. When a file has not been in use in 60 seconds, the process governing it terminates and frees up the resources on that file. It works reasonably well. The problem, however, is that some torrents have more files than the file descriptor limit. When we check the file upon starting up, we unfortunately open more than 1024 and then hit the limit.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;The Solution&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;The solution is deceptively simple. We add a janitor process to the game. Whenever a new file is opened the janitor gets informed and the file process enters itself into an ETS table. Whenever we do an operation on the file a timestamp is bumped in the ETS table. This goes on and on; if a process dies, a monitor in the janitor cleans out the entry from the ETS table.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;Now, whenever a new file is opened we check the size of the table against a high watermark, 128 by default. If more processes are opened, we extract the full table and order it by last bump. Thus, the first elements in the resulting list are the processes which have been used the farthest back in time. We then ask enough of these to terminate to bring ourselves back under a low watermark - ensuring we won't be hitting the resource collection all the time we add a new file system process to the game.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;Updating the ETS table is expected to be rather cheap. The table is public, so each file governing process maintains its own entry. I don't think they will spend much time waiting for each other on the table. And if they do, there is always {write_concurrency, true} we can set on the table.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/5411139659011156551-9098078301257594636?l=jlouisramblings.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Jlouis</name>
			<email>noreply@blogger.com</email>
			<uri>http://jlouisramblings.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">JLOUIS Ramblings</title>
			<subtitle type="html">Musings of a mathematically oriented Computer Scientist. Anything that tickles my brain might go in here, be it Computer Science, mathematics, society, relationships, sex, 0xf00d, or pets.</subtitle>
			<link rel="self" href="http://jlouisramblings.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-5411139659011156551</id>
			<updated>2010-06-30T19:01:36+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">WaveOne, a wave server and client by ProcessOne</title>
		<link href="http://www.process-one.net/en/blogs/article/waveone_a_wave_server_by_processone/"/>
		<id>tag:process-one.net,2010:en/blogs/3.2759</id>
		<updated>2010-05-21T13:31:42+00:00</updated>
		<content type="html">&lt;p&gt;WaveOne, the new wave server developped by ProcessOne, has been demoed at Google I/O.&lt;/p&gt; &lt;p&gt;&lt;span&gt;ProcessOne has been invited to join the Wave area in  Google Developer Sandbox at Google I/O 2010 in San Francisco.&lt;br /&gt;&lt;br /&gt;Micka&amp;euml;l  R&amp;eacute;mond, the founder of ProcessOne, has been invited by Google in the  context of the Google I/O event, to write &lt;a href=&quot;http://googlecode.blogspot.com/2010/05/waveone-wave-server-implementation.html&quot;&gt;a blog post to introduce  WaveOne&lt;/a&gt;, our own wave server implementation.&lt;br /&gt;&lt;br /&gt;WaveOne is basically  an ejabberd module, so it is written in Erlang. It features an  Operationnal Transform engine, as well as a Wave Store. It means that  with the help of a client, you can - on your own WaveOne server  installation - create, edit, store and share wavelets.&lt;br /&gt;&lt;br /&gt;The  WaveOne extension to our XMPP client OneTeam enables you to manage your  wavelets (and blips), like create, edit, as well as add participants to  wavelets, still on your own WaveOne server installation.&lt;br /&gt;&lt;br /&gt;With the  WaveOne client and server, you can collaborate in real-time internally,  as well as externally, thanks to the federation capability. WaveOne  supports federation with Google Wave in both directions. You can host  the wavelets on your local server and have remote participants or you  can do the reverse and participate to wavelets hosted on the Google  server. This enables you to add participants, or be added as  participant, to wavelets hosted on any wave server. Everything works in  real time with character by character support.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Here is a screenshot that shows a wavelet (containing two blips) edited both on Google Wave and ProcessOne's WaveOne:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;212&quot; src=&quot;http://www.process-one.net/images/uploads/WaveOne_federation.png&quot; width=&quot;485&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;br /&gt;The result is  much like having your own e-mail or XMPP client and server under your  own control. This is built on the power of XMPP-based federation.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;A handy feature of our WaveOne implementation is the capability to share a textarea of a webpage, for collaborative real-time text editing. This has been demoed at Google I/O, and has received much interest. Here are some sample screenshots.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The user &lt;/span&gt;&lt;span&gt;right-clicks in &lt;/span&gt;&lt;span&gt;a textarea, and shares it:&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;220&quot; src=&quot;http://www.process-one.net/images/uploads/WaveOne_share_textarea_on_wave.png&quot; width=&quot;295&quot; /&gt;&lt;/p&gt;
&lt;p&gt;He adds participants to the wavelet:&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;102&quot; src=&quot;http://www.process-one.net/images/uploads/WaveOne_add_paticipants.png&quot; width=&quot;275&quot; /&gt;&lt;/p&gt;
&lt;p&gt;All participants can collaboratively edit the text in real-time:&lt;/p&gt;
&lt;p&gt;&lt;img height=&quot;155&quot; src=&quot;http://www.process-one.net/images/uploads/WaveOne_edit_wavelet.png&quot; width=&quot;348&quot; /&gt;&lt;/p&gt;</content>
		<author>
			<name>Nicolas Vérité</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:07:05</id>
			<updated>2010-07-05T20:46:26+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry>
		<title type="html">Migrate Notes data to CouchDB: Smart Notes 2 Couch</title>
		<link href="http://damienkatz.net/2010/05/smart_notes_2_couch.html"/>
		<id>tag:damienkatz.net,2010://1.567</id>
		<updated>2010-05-21T00:54:35+00:00</updated>
		<content type="html" xml:lang="en">&lt;blockquote&gt;&lt;div&gt;can migrate your Lotus Domino data to CouchDB data. It's free and it's open source.&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;http://www.smartlotus.com/smart-notes-2-couch.html&quot;&gt;http://www.smartlotus.com/smart-notes-2-couch.html&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">I'm in your phone</title>
		<link href="http://damienkatz.net/2010/05/im_in_your_phone.html"/>
		<id>tag:damienkatz.net,2010://1.569</id>
		<updated>2010-05-21T00:53:14+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://blog.couch.io/post/613382692/look-at-what-nitin-did-here-after-registering-at&quot;&gt;CouchDB on Motorola Droid&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://28.media.tumblr.com/tumblr_l2pzv0EYrS1qb3bkxo1_500.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://blog.couch.io/post/616185137/look-at-my-couch-it-runs-on-a-nokia-n900&quot;&gt;And on Nokia n900&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">CouchDB Rap</title>
		<link href="http://damienkatz.net/2010/05/couchdb_rap.html"/>
		<id>tag:damienkatz.net,2010://1.568</id>
		<updated>2010-05-21T00:44:40+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;&lt;p&gt;&lt;a href=&quot;http://vimeo.com/11852209&quot;&gt;I Use Couch DB&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.h-online.com/open/features/Couchio-rap-literally-about-CouchDB-1004451.html&quot;&gt;Premiered today on The H&lt;/a&gt;. Nice.&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">17 May 2010: Erlang Solutions awarded a Knowledge Transfer Partnership with the Kent Business School</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1159"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1159</id>
		<updated>2010-05-17T10:15:58+00:00</updated>
		<content type="html">Erlang Solutions is proud to announce that a third KTP project has been accepted by the &lt;a href=&quot;http://www.ktponline.org.uk/&quot; target=&quot;_blank&quot;&gt;Knowledge Partnerships Programme&lt;/a&gt; (KTP). This is in addition to the Reusable Components project that recently completed and the E-Learning/E-Certification Project that began in October 2009. This project will be a strategic marketing project together with the University of Kent, who have been our Academic partners in the other two projects and with whom Erlang Solutions has a strong partnership.&lt;br /&gt;&lt;br /&gt;The main purpose of the project will be to establish and nurture a marketing orientation within the company and improve current marketing processes from a tactical and strategic perspective.</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-07-30T06:15:46+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">10 May 2010: Erlang Solutions Announces Opening of New Office in Stockholm, Sweden</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1155"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1155</id>
		<updated>2010-05-16T19:16:06+00:00</updated>
		<content type="html">Erlang Solutions Ltd has opened a new office in central Stockholm. The new office and and staff with extensive knowledge of Erlang will allow the company to better serve its large client-base in Sweden and worldwide. The expansion also provides an expanded training portfolio and facilities. It is envisaged that Erlang community will meet here at regularly organised Erlang User Group Meetings. In addition Erlang Solutions will be able to accommodate more students for internships, training and certification.&lt;br /&gt;&lt;br /&gt;Erlang Solutions&amp;#8217; new office is located at&lt;span&gt; Saltm&amp;#228;targatan 5, 113 59 Stockholm,&lt;/span&gt; &lt;span&gt;Sweden&lt;/span&gt; and can be reached by phone at &lt;span&gt;+46 - (0) 8 - 120 424 00&lt;/span&gt;</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-07-30T06:15:46+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">CouchDB Case Studies</title>
		<link href="http://damienkatz.net/2010/05/couchdb_case_studies.html"/>
		<id>tag:damienkatz.net,2010://1.566</id>
		<updated>2010-05-06T21:10:31+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;We've just put up our new &lt;a href=&quot;http://www.couch.io/case-studies&quot;&gt;CouchDB case studies page&lt;/a&gt;. So far we have the &lt;a href=&quot;http://www.bbc.co.uk/&quot;&gt;BBC&lt;/a&gt;, &lt;a href=&quot;http://www.assaydepot.com/&quot;&gt;Assay Depot&lt;/a&gt; and &lt;a href=&quot;http://www.interactivemediums.com/&quot;&gt;Interactive Mediums&lt;/a&gt;, and more in the works. And if you are interested in being profiled for a case study, &lt;a href=&quot;http://blog.couch.io/post/576869253/new-couchdb-case-studies-posted-and-we-want-to-hear&quot;&gt;see this post&lt;/a&gt;.&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Google Denies Our Commercial</title>
		<link href="http://damienkatz.net/2010/05/google_denies_our_commercial.html"/>
		<id>tag:damienkatz.net,2010://1.564</id>
		<updated>2010-05-05T22:26:54+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;Recently Chris and Claire &lt;a href=&quot;http://www.vimeo.com/11062756&quot;&gt;produced a commercial for Couchio and CouchDB&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;We tried to run it on real TV via Google AdWords, but they denied it:&lt;/p&gt;

&lt;blockquote&gt;&lt;div&gt;

&lt;p&gt;Hello Claire,&lt;/p&gt;

&lt;p&gt;Thank you for your email. I have reviewed your account and found that the ad was rejected for the following reasons:&lt;/p&gt;

&lt;p&gt; * Your ad clearly and accurately describes your business, product, or service.&lt;/p&gt;

&lt;p&gt; * Rich Media and TV ads: your ad clearly identifies the sponsor of the ad.&lt;/p&gt;

&lt;p&gt; * Online Audio and TV ads: Your ad does not include a 'shout-out' that is not commercial in nature.&lt;/p&gt;

&lt;p&gt;Please note that the audio quality is not clear enough to explain the business information. This is the reason why your ad was disapproved. I suggest you improve the audio quality and resubmit your ad.&lt;/p&gt;

&lt;p&gt;Please follow these technical Specifications and Instructions in future:&lt;br /&gt;
 &lt;br /&gt;
&lt;a href=&quot;http://adwords.google.com/support/aw/bin/answer.py?hl=en&amp;answer=78641&quot;&gt;http://adwords.google.com/support/aw/bin/answer.py?hl=en&amp;amp;answer=78641&lt;/a&gt;&lt;br /&gt;
 &lt;br /&gt;
Once you edit your ad to comply with our policies, your ad is automatically resubmitted back to us for review. We appreciate your effort in editing your ad.&lt;br /&gt;
 &lt;br /&gt;
Sincerely, &lt;br /&gt;
 &lt;br /&gt;
Shilpi&lt;br /&gt;
Google AdWords&lt;br /&gt;
&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;I think it's that they just can't handle our awesomeness, but they claim it's something about the audio. I'm thinking we'll resubmit with the lyrics scrolling at the same time, so there is no confusion what's being sung.&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Announcing New Erlang Native GeoCouch</title>
		<link href="http://damienkatz.net/2010/05/announcing_new_erlang_native_g.html"/>
		<id>tag:damienkatz.net,2010://1.565</id>
		<updated>2010-05-05T22:25:58+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;&lt;a href=&quot;http://vmx.cx/cgi-bin/blog/index.cgi/geocouch-the-future-is-now%3A2010-05-03%3Aen%2CCouchDB%2CPython%2CErlang%2Cgeo&quot;&gt;GeoCouch: The Future is Now&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;&lt;div&gt;An idea has become reality. Exactly two years after the blog post with the initial vision, a new version of GeoCouch is finished. It's a huge step forward. The first time the dependencies were narrowed down to CouchDB itself. No Python, no SpatiaLite any longer, it's pure Erlang. GeoCouch is tightly integrated with CouchDB, so you'll get all the nice features you love about CouchDB.&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;Awesome work Volker!&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Availability, the Cloud and Everything</title>
		<link href="http://www.joeandmotorboat.com/2010/05/31/availability-the-cloud-and-everything/"/>
		<id>http://www.joeandmotorboat.com/?p=1016</id>
		<updated>2010-05-01T17:37:42+00:00</updated>
		<content type="html">&lt;p&gt;Finally posted my presentation at &lt;a href=&quot;http://erlang-factory.com/conference/SFBay2010&quot;&gt;Erlang Factory&lt;/a&gt;, &lt;a href=&quot;http://www.washingtontechnology.org/&quot;&gt;WTIA Cloud SIG&lt;/a&gt; and &lt;a href=&quot;http://www.meetup.com/Seattle-Hadoop-HBase-NoSQL-Meetup/&quot;&gt;Seattle Scalability Meetup&lt;/a&gt; here on the blog.&lt;/p&gt;
&lt;div id=&quot;__ss_3567217&quot;&gt;&lt;strong&gt;&lt;a href=&quot;http://www.slideshare.net/logicalstack/availability-the-cloud-and-everything&quot; title=&quot;Availability, the Cloud and Everything&quot;&gt;Availability, the Cloud and Everything&lt;/a&gt;&lt;/strong&gt;
&lt;div&gt;View more &lt;a href=&quot;http://www.slideshare.net/&quot;&gt;presentations&lt;/a&gt; from &lt;a href=&quot;http://www.slideshare.net/logicalstack&quot;&gt;logicalstack&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;</content>
		<author>
			<name>Joe's blog</name>
			<uri>http://www.joeandmotorboat.com</uri>
		</author>
		<source>
			<title type="html">Joe's Blog!</title>
			<link rel="self" href="http://www.joeandmotorboat.com/feed/"/>
			<id>http://www.joeandmotorboat.com/feed/</id>
			<updated>2010-07-30T06:15:19+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Create a Custom CouchDB indexer</title>
		<link href="http://damienkatz.net/2010/04/create_a_custom_couchdb_indexe.html"/>
		<id>tag:damienkatz.net,2010://1.563</id>
		<updated>2010-04-30T02:43:04+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;Recently I worked with &lt;a href=&quot;http://vmx.cx/&quot;&gt;Volker Mische&lt;/a&gt; to help him create a new R-Tree geo-spacial indexer for CouchDB, the details of which he'll be announcing soon.&lt;/p&gt;

&lt;p&gt;And not only that, he took the time to write up a tutorial how to create you own customer indexer. If you wanted to write a new full text indexer in Erlang for CouchDB, this tutorial is the place to start. Awesome work!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://vmx.cx/couchdb/tutorial/indexer.html&quot;&gt;http://vmx.cx/couchdb/tutorial/indexer.html&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">ProcessOne at Google I/O Developer Sandbox 2010</title>
		<link href="http://www.process-one.net/en/blogs/article/processone_at_google_i_o_developer_sandbox_2010/"/>
		<id>tag:process-one.net,2010:en/blogs/3.2591</id>
		<updated>2010-04-29T15:03:47+00:00</updated>
		<content type="html">&lt;p&gt;We have been selected to demonstrate our WaveOne server and preview client in &lt;a href=&quot;http://code.google.com/events/io/2010/sandbox.html&quot; title=&quot;ProcessOne at Google Developer Sandbox 2010&quot;&gt;Google I/O developer sandbox&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;ProcessOne will be presenting many of its new products as a preview technology implementation, among which:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WaveOne server and extension module for &lt;a href=&quot;http://www.ejabberd.im/&quot;&gt;ejabberd&lt;/a&gt; XMPP server.&lt;/li&gt;
&lt;li&gt;Various example client implementations using the Wave protocol from XMPP: &lt;a href=&quot;http://www.process-one.net/en/solutions/oneteam/&quot;&gt;OneTeam for Firefox&lt;/a&gt; client extension, and &lt;a href=&quot;http://tkabber.jabber.ru/&quot;&gt;Tkabber&lt;/a&gt; support.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://xmpp.org/extensions/xep-0166.html&quot;&gt;Jingle&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/p/jinglenodes/&quot;&gt;Jingle&lt;/a&gt; &lt;a href=&quot;http://xmpp.org/extensions/inbox/jingle-nodes.html&quot;&gt;Nodes&lt;/a&gt; XMPP calling with our OneTeam client.&lt;/li&gt;
&lt;li&gt;The roadmap for the future of our XMPP and Wave collaborative platform.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We are also preparing various surprises for the people who can attend Google I/O (Did I say Android?).&lt;/p&gt;
&lt;p&gt;This is going to be an extraordinary event for us. See you there!&lt;/p&gt;
     [&lt;a href=&quot;http://www.process-one.net/en/blogs/article/processone_at_google_i_o_developer_sandbox_2010/&quot;&gt;More...&lt;/a&gt;]</content>
		<author>
			<name>Mickaël Rémond</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:07:05</id>
			<updated>2010-07-05T20:46:26+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry>
		<title type="html">Haskell vs. Erlang for bittorent clients</title>
		<link href="http://jlouisramblings.blogspot.com/2010/04/haskell-vs-erlang-for-bittorent-clients.html"/>
		<id>tag:blogger.com,1999:blog-5411139659011156551.post-2438846119259619420</id>
		<updated>2010-04-26T17:51:01+00:00</updated>
		<content type="html">&lt;div id=&quot;haskell-vs.erlang&quot;&gt;&lt;h1&gt;Haskell vs. Erlang&lt;/h1&gt;&lt;p&gt;Since I wrote a bittorrent client in both Erlang and Haskell, etorrent and combinatorrent respectively, I decided to put up some bait. This might erupt in a language war and “My language is better than yours”, but I feel I am obligated to write something subjective. Here is to woes of programming in Haskell and Erlang.&lt;/p&gt;&lt;p&gt;Neither Haskell, nor Erlang was a first language for me. I have programmed serious programs in C, Standard ML, Ocaml, Python, Java and Perl; tasted the cake of Go, Javascript, Scheme and Ruby; and has written substantial stuff in Coq and Twelf. I love static type systems, a bias that will rear its ugly head and breathe fire.&lt;/p&gt;&lt;p&gt;I have written Haskell code seriously since 2005 and Erlang code seriously since 2007. I have programmed functionally since 1997 or so. My toilet reading currently is “Categories for the working mathematician” by Mac Lane. Ten years ago it was “ML for the working programmer” by Paulson.&lt;/p&gt;&lt;p&gt;Enough about me.&lt;/p&gt;&lt;div id=&quot;caveats:&quot;&gt;&lt;h2&gt;Caveats:&lt;/h2&gt;&lt;p&gt;With any language war material follows a disclaimer and a healthy dose of caveats. This is subjective. You have to live with it being subjective. My writing can’t be objective and colorful at the same time. And I like colors in my life. Also, it is no fun reading a table listing the comparison. Rather, I will try to make it into a good foil duel with attacks, parries, guards, pierces, bananas, and barbed wire.&lt;/p&gt;&lt;p&gt;I built etorrent in Erlang first and combinatorrent in Haskell second. Hence, the 2nd time around, with the sole goal of redoing the functionality of etorrent was much easier and could proceed much faster. The Erlang code is slightly fattier at 4.2K lines versus 3.6K lines of Haskell (SLOCs). The performance of the two clients is roughly equal, but more time was spent at optimizing the Haskell code.&lt;/p&gt;&lt;p&gt;My hypothesis is this: The Erlang VM is much more optimized at the IO layer than the current IO layer I use in GHC (specifically, the way incoming data is handled allocates more memory. This might change in the future do to a new IO layer). GHC kills the Erlang VM for everything else though, perhaps including message passing.&lt;/p&gt;&lt;p&gt;Also, the quality of the Erlang code could be better, relatively compared to the Haskell code.&lt;/p&gt;&lt;p&gt;Enough!&lt;/p&gt;&lt;p&gt;Enough with the caveats!&lt;/p&gt;&lt;/div&gt;&lt;div id=&quot;haskell-cons:&quot;&gt;&lt;h2&gt;Haskell cons:&lt;/h2&gt;&lt;p&gt;What weighs against using Haskell for the project? First is laziness. Sometimes you want your code to be strict and sometimes lazy. In combinatorrent, we do some statistics which we don’t really need to calculate unless we want to present them. Stuff like bytes uploaded and downloaded for instance. Since you do not necessarily ask for these statistics, the compiler is free to build up thunks of the calculation and you have a neat little space leak. This is a recurring problem until you learn how to harness the strictness annotations of Haskell. Then the problem disappears.&lt;/p&gt;&lt;p&gt;IO in Haskell is somewhat weak if you naively assume a String is fast. But there is help from Bytestrings, attoparsec and low-level Socket networking. Combinatorrent could use more help with getting the speed up here. I have substituted the IO layers lowest level some 2–3 times in combinatorrent. Contrast this with Erlang, where the original protocol parser and IO is the one still standing. If you want fast network IO in Haskell, you should be using bytestrings and network-bytestring. It is not worth the simplicity going over String in my experience.&lt;/p&gt;&lt;p&gt;The GHC compiler has, comparatively, more performance regressions compared to the Erlang VM. It should come as no surprise: GHC is acting as both a research vehicle and a compiler implementation. I want to stress however, that this has not worried me a lot. When asking the GHC developers for help, the response has been fast and helpful, and in every case it was easy to fix or work around. Also, change is a necessary thing if you want to improve.&lt;/p&gt;&lt;/div&gt;&lt;div id=&quot;haskell-pros:&quot;&gt;&lt;h2&gt;Haskell pros:&lt;/h2&gt;&lt;p&gt;Haskell has one very cool thing: Static typing (remember the bias!). The type system of Haskell is the most advanced type system for a general purpose language in existence. The only systems which can beat it are theorem provers like Coq, and they are not general purpose programming languages (Morriset and the YNot team might disagree though!). Static typing has some really cool merits. Bugs are caught fast and early; types ensure few corner cases in the programs (why check for null when it can’t be represented). The types is my program skeleton and the program inhabiting the type is the flesh. Getting the skeleton right yields small and succinct programs. The abstraction possibilities from this is unparalleled in any language I have seen (and I’ve seen a few).&lt;/p&gt;&lt;p&gt;The GHC compiler provides programs which have excellent execution speed. You don’t need to worry a lot about speed when the compiler simply fixes most of the problems for you. This in turn means that you can write abstract code without worrying too much about the result. This yields vastly more general and simpler programs.&lt;/p&gt;&lt;p&gt;One very big difference in the implementations is that of STM channels versus Erlangs message passing. In Erlang, each process has a mailbox of unbounded size. You send messages to the mailbox, identified by the process ID of the mailbox owner. In Haskell, we use STM Channels for most communication. Thus, you send messages not to the PID of a process, but to a specific channel. This effectively changes some rules in channel network configuration. In Erlang you must either globally register a process or propagate PIDs. In Haskell, channels are created and then propagated to communicating parties. I find the Haskell approach considerably easier - but also note that in a statically typed language, channels is the way to go. The sum type for a PID mailbox would be cumbersome in comparison.&lt;/p&gt;&lt;p&gt;Haskell has excellent library and data structure support. For instance you have access to priority search queues via Hackage. PSQueues are useful for implementing the piece histogram in a bittorrent client: knowing how rare a given piece is so you can seek to fetch the rarest first.&lt;/p&gt;&lt;p&gt;Haskell can create (im-)mutable (un-)boxed arrays. These are useful in a bittorrent client in several places. Immutable arrays for storing knowledge about pieces is an example. Or bit-arrays for storing knowledge about the pieces a given peer has. Erlang has no easy access to these and no guarantee of the data representation.&lt;/p&gt;&lt;p&gt;Bryan O’Sullivans attoparsec library allows for incremental parsing. When you get a new chunk of data from the network, you feed it to attoparsec. It will either give you a parsed message and the remaining bytes, or it will hand you back a continuation. This continuation, if invoked with more food, will continue the parsing. For network sockets the incrementality is pure win.&lt;/p&gt;&lt;p&gt;The GHC compiler has some awesome profiling tools, including a powerful heap profiler. Using this, the run-time and memory usage of combinatorrent was brought down.&lt;/p&gt;&lt;p&gt;Finally, testing in Haskell is easy. QuickCheck and Test.Framework provides a —tests target built into the combinatorrent binary itself. Self tests are easy.&lt;/p&gt;&lt;/div&gt;&lt;div id=&quot;haskell-mistakes:&quot;&gt;&lt;h2&gt;Haskell mistakes:&lt;/h2&gt;&lt;p&gt;I made some mistakes when writing the Haskell client. For one I relied on the CML library until I realized STM would do an equal or better job. The amount of Haskell developers with STM experience compared to the CML head-count made the decision to change easy.&lt;/p&gt;&lt;p&gt;Furthermore, I should have focused on laziness earlier in the process. The first combinatorrent releases leak memory because of lazy thunk buildup. The latter versions, after I understood it intuitively, does not leak.&lt;/p&gt;&lt;/div&gt;&lt;div id=&quot;erlang-cons:&quot;&gt;&lt;h2&gt;Erlang cons:&lt;/h2&gt;&lt;p&gt;In Erlang, dynamic typing is the norm. Rather than enforce typing, you can get warnings by a type analyzer tool, the dialyzer, if need be. Running this on the code is a good idea to weed out some problems quickly. When building etorrent I had much use of the dialyzer and used a at that time experimental extension: spec() specifications. Yet, I think that 19/20 errors in my erlang programs were errors which a type system would have caught easily. This means you spend more time actually running the program and observing its behavior. Also note that dynamic typing hurts less in Erlang compared to other languages. A process is comprehensible in its own right and that reduces the interface to the process communication - a much simpler task.&lt;/p&gt;&lt;p&gt;Etorrent has less stability than combinatorrent and has erred more. Yet, this is no problem for a bittorrent client since the supervisor-tree in Erlang/OTP will automatically restart broken parts of the system. For a bittorrent client we can live with a death once a week or once a day without any troubles.&lt;/p&gt;&lt;p&gt;You have no mutability in Erlang and you have far less options for data representation. This in turn make certain algorithms rather hard to express or you have to opt for variant with a larger space usage. There were no Cabal-equivalent at the time I wrote the code and thus fewer libraries to choose from.&lt;/p&gt;&lt;p&gt;For the built-in libraries, the HTTP library was more strict with respect to correctness. In turn, many trackers would not communicate with it and I had to provide a wrapper around the library. Today, this might have changed though. Haskells HTTP library worked out of the box with no changes.&lt;/p&gt;&lt;p&gt;Erlangs syntax, compared to Haskell, is ugly, clunky and cumbersome. Make no mistake though: Tanks are ugly, clunky and cumbersome. It does not make tanks less menacing.&lt;/p&gt;&lt;/div&gt;&lt;div id=&quot;erlang-pros:&quot;&gt;&lt;h2&gt;Erlang pros:&lt;/h2&gt;&lt;p&gt;One application SASL. SASL is a system logger which will record in a ring-buffer any kind of process death and process restart. I used this a lot when developing. I would load a couple of torrents in the client and go to bed. Next morning I would check the SASL log for any error that might have occurred and fix those bugs. This way of developing is good for a bittorrent client: utmost stability is not needed. We just to get the number of errors below a certain threshold. Rather than waste time fixing a bug which only occurs once every year, we can concentrate on the things that matter.&lt;/p&gt;&lt;p&gt;The IO layer in Erlangs VM is FAST! It is written in C, and it is optimized heavily because this is what Erlang does best. For file IO it uses asynchronous threads to circumvent having to wait on the kernel. For the network, it plugs into epoll() getting good performance in turn.&lt;/p&gt;&lt;p&gt;The Beam VM of Erlang is a beast of stability. Basically, it doesn’t quit unless you nuke it from orbit. One of the smaller things I learned some weeks ago was the rudimentary flow control trick. Erlang schedules by counting reductions in an Erlang process and then switching process context when it has no more reductions in its time share. Sending a message never fails but it costs reductions proportional to the queue size of the receiving process. Hence, many senders have a harder time overloading a single receiver. The trick is simple, easily implementable and provides some simple flow control. While not fail-safe, it ups the ante for when communication overload happens.&lt;/p&gt;&lt;p&gt;Erlang has OTP, the Open Telecom Platform, which is a callback-framework for processes. You implement a set of callbacks and hand over control to the OTP-portion of your process. OTP then handles a lot of the ugly, gritty details leaving your part simple. OTP also provides the supervision of processes, restarting them if they err. Supervisor-processes form trees so &lt;em&gt;they&lt;/em&gt; are in turn supervised. It isn’t turtles all the way down in an Erlang VM…&lt;/p&gt;&lt;p&gt;Erlang executes fast enough for most things. Haskell gives you faster execution, but Erlang was more than adequate for a bittorrent client in the speed department. As an example of how this plays together with the IO layer, an early version of etorrent could sustain 700 megabit network load on a local network of 1 gigabit when seeding. The current version of etorrent can do the same as a seeder I suspect. Also, message passing in Erlang is blazing fast. It feels like a function call - a key to good Erlang I think.&lt;/p&gt;&lt;p&gt;The Erlang shell can easily be used as a poor mans user interface. Etorrent simply responds to some functions in the shell, showing status of the running system. I suspect GHCi can do the same, but I never got around to doing it and it doesn’t seem as easy to pull off.&lt;/p&gt;&lt;p&gt;I love the Erlang way of programming. You assume your code does the right thing and let it crash otherwise. If it crashes too often you handle that case. Code is not lingered with error handling for things that never happen and should it happen occasionally, the supervisor tree saves the day.&lt;/p&gt;&lt;/div&gt;&lt;div id=&quot;erlang-mistakes:&quot;&gt;&lt;h2&gt;Erlang mistakes:&lt;/h2&gt;&lt;p&gt;Unfortunately, I made a number of mistakes in Etorrent. Most of these has to do with being the first version. Fred P. Brooks hinted that you want to throw away things when building the first version. And I did. I used ETS tables in places where they are not good. ETS is a table in which you can store any erlang term and later retrieve it. They give you a way to circumvent the representation limitation in Erlang. But they are no silver bullet: When you pull out a term, you copy it to the process pulling it. When your terms are 4–8 megabyte in size, that hurts a lot.&lt;/p&gt;&lt;p&gt;I relied far too much on mnesia, the database in Erlang. Mnesia is basically using software-transactional-memory so locking is optimistic. When you have something like 80 writers wanting access to the same row in a table, then the system starves. Also, there is no need for a bittorrent application to require a mnesia store. A simple serialization of key data to a file based on a timer is more than adequate.&lt;/p&gt;&lt;p&gt;I made several mistakes in the process model. I thought that choking was local to a torrent while in reality it is a global thing for all torrents currently being downloaded. These reorganizations require quite some refactoring - and missing in the static typing department these are somewhat more expensive compared to Haskell refactorings.&lt;/p&gt;&lt;p&gt;I thought autotools were a good idea. It is not. Autotools is the Maven of C programming.&lt;/p&gt;&lt;p&gt;Finally, I shedded unit-tests. In a dynamically typed environment you need lots and lots of these. But I decided against them early on. In hindsight this was probably a mistake. While unit-testing Erlang code is hard, it is by no means impossible.&lt;/p&gt;&lt;/div&gt;&lt;div id=&quot;future:&quot;&gt;&lt;h2&gt;Future:&lt;/h2&gt;&lt;p&gt;The future brings exciting things with it. I will continue Combinatorrent development. I am almost finished with the Fast-extension (BEP 0006) for combinatorrent and have some more optimization branches ready as well. I still follow Erlang in general because it is an interesting language with a lot of cool uses. I do check that etorrent compiles on new releases of Erlang. If anyone shows interest in any of the client implementations, feel free to contact me. I will happily answer questions.&lt;/p&gt;&lt;p&gt;There is no clear winner in the duel. I &lt;em&gt;prefer&lt;/em&gt; Haskell, but I am biased and believe in static typing. Yet I &lt;em&gt;like&lt;/em&gt; programming in Erlang - both languages are good from different perspectives.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/5411139659011156551-2438846119259619420?l=jlouisramblings.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Jlouis</name>
			<email>noreply@blogger.com</email>
			<uri>http://jlouisramblings.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">JLOUIS Ramblings</title>
			<subtitle type="html">Musings of a mathematically oriented Computer Scientist. Anything that tickles my brain might go in here, be it Computer Science, mathematics, society, relationships, sex, 0xf00d, or pets.</subtitle>
			<link rel="self" href="http://jlouisramblings.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-5411139659011156551</id>
			<updated>2010-06-30T19:01:36+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">26 April 2010: Hans Nilsson joins Erlang Solutions as Senior Consultant</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1152"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1152</id>
		<updated>2010-04-26T10:30:42+00:00</updated>
		<content type="html">Erlang Solutions Ltd proudly welcomes one of the world's most experienced and capable Erlang experts into our team.&lt;br /&gt;&lt;br /&gt;Hans Nilsson joined the Ericsson Computer Science Lab in 1988, the year after Joe Armstrong. For the first two years, he worked on the development of the highly regarded SICSTUS Prolog. In 1995 together with&amp;#160; Claes Wikstr&amp;#246;m, he developed the Mnesia DBMS and Mnemosyne query language, and then went on to study the budding Voice over IP field. He implemented his first Erlang-based SIP stack in 1998, while the standard (RFC2543) was not yet in stable draft. Hans presented his SIP-ISDN Gateway at the Erlang User Conference 1997.&lt;br /&gt;&lt;br /&gt;After a couple of years developing a residential Ethernet switch at Ericsson, Hans returned to Voice over IP. He established himself as one of Ericsson's leading SIP experts, and was the company's representative in the GSM Association SIP Technical Expert Group. Meanwhile, he was the technical lead on a large product development project based on his SIP implementation. Before joining Erlang Solutions, he worked in a tiger team doing advanced prototyping with Erlang in close cooperation with the Intel Performance Lab.&lt;br /&gt;&lt;br /&gt;Hans is also a key member of the &lt;a href=&quot;http://www.protest-project.eu/&quot; target=&quot;_blank&quot;&gt;ProTest&lt;/a&gt; EU Project, where his work on property-baseddata mining of packet trace logs and QuickCheck verification of SIP parsers have been highly influential. As Erlang Solutions is an active member of that project, his involvement will continue.&lt;br /&gt;&lt;br /&gt;With the addition of Hans Nilsson, Erlang Solutions is able to offer world-class expertise in the Voice over IP field.</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-07-30T06:15:46+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">19 April 2010: Erlang Solutions at TFP 2010 and AMOOCON2010</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1150"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1150</id>
		<updated>2010-04-19T13:01:45+00:00</updated>
		<content type="html">We are proud to announce that the talk abstracts that Erlang Solutions' employees submitted have been accepted to TFP2010 and AMOOCON2010.&lt;br /&gt;&lt;br /&gt;Michal Ptaszek, Consultant at Erlang Solutions Ltd. will be giving a talk on &quot;&lt;a href=&quot;http://www.erlang-consulting.com/../../events/2/entry/1105&quot; target=&quot;_self&quot;&gt;ComputErl - Erlang-based Framework for Many Task Computing&lt;/a&gt;&quot; at the Symposium on Trends in Functional Programming at the University of Oklahoma this May and Tino Breddin, Systems Engineer at Erlang Solutions Ltd, will be giving a talk on &quot;&lt;a href=&quot;http://www.erlang-consulting.com/../../events/2/entry/1149&quot; target=&quot;_self&quot;&gt;Concurrent Programming with Erlang&lt;/a&gt;&quot; at the AMOOCON2010 in June 2010.&lt;br /&gt;&lt;br /&gt;If you are planing to attend any of these conferences, &lt;span&gt;meet us there!&lt;/span&gt;</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-07-30T06:15:46+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Why is this man so damn happy?</title>
		<link href="http://damienkatz.net/2010/04/why_is_this_man_so_damn_happy.html"/>
		<id>tag:damienkatz.net,2010://1.562</id>
		<updated>2010-04-17T19:34:46+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://vimeo.com/10993778&quot;&gt;CouchDB!&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en-US">
		<title type="html">NetBeans(6.8) plugin for Scala 2.8.0 RC1</title>
		<link href="http://blogtrader.net/blog/NetBeansPluginForScala2_8_0RC1"/>
		<id>http://blogtrader.net/blog/NetBeansPluginForScala2_8_0RC1</id>
		<updated>2010-04-15T05:02:06+00:00</updated>
		<content type="html">&lt;p&gt;
I'm please to announce the &lt;a class=&quot;wiki&quot; href=&quot;http://blogtrader.net/wiki/NetBeans&quot;&gt;NetBeans&lt;/a&gt; (6.8) plugin for Scala 2.8.0
RC1 is available now. It's a maintain release to catch up with Scala
2.8.0 RC1.
&lt;/p&gt;
&lt;p&gt;
The packed plugins is downloadable at:
&lt;a class=&quot;ext-link&quot; href=&quot;http://sourceforge.net/projects/erlybird/files/nb-scala/6.8v1.1.0rc2/&quot;&gt;&lt;span class=&quot;icon&quot;&gt; &lt;/span&gt;http://sourceforge.net/projects/erlybird/files/nb-scala/6.8v1.1.0rc2/&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
It requires Scala 2.8.0 RC1, which is available at:
&lt;a class=&quot;ext-link&quot; href=&quot;http://www.scala-lang.org/downloads&quot;&gt;&lt;span class=&quot;icon&quot;&gt; &lt;/span&gt;http://www.scala-lang.org/downloads&lt;/a&gt;. For maven project, it's under
&lt;a class=&quot;ext-link&quot; href=&quot;http://www.scala-tools.org/repo-releases&quot;&gt;&lt;span class=&quot;icon&quot;&gt; &lt;/span&gt;http://www.scala-tools.org/repo-releases&lt;/a&gt;, with version number
&quot;2.8.0.RC1&quot;
&lt;/p&gt;
&lt;p&gt;
Please refer to &lt;a class=&quot;ext-link&quot; href=&quot;http://wiki.netbeans.org/Scala68v1&quot;&gt;&lt;span class=&quot;icon&quot;&gt; &lt;/span&gt;http://wiki.netbeans.org/Scala68v1&lt;/a&gt; for the
installation/upgrading information.
&lt;/p&gt;</content>
		<author>
			<name>Caoyuan's Blog</name>
			<uri>http://blogtrader.net/blog</uri>
		</author>
		<source>
			<title type="html">BlogTrader - Blog</title>
			<subtitle type="html">About Caoyuan's Blog</subtitle>
			<link rel="self" href="http://blogtrader.net/page/dcaoyuan/feed/entries/atom"/>
			<id>http://blogtrader.org/page</id>
			<updated>2010-07-30T06:15:12+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">SpringSource / VMWare Acquire Rabbit Technologies</title>
		<link href="http://www.lshift.net/blog/2010/04/14/springsource-vmware-acquire-rabbit-technologies"/>
		<id>http://www.lshift.net/blog/?p=493</id>
		<updated>2010-04-14T13:05:28+00:00</updated>
		<content type="html">&lt;p&gt;SpringSource, a division of VMware, Inc. today announced the acquisition by VMware of Rabbit Technologies, Ltd, a company set up by LShift and partners Monadic and CohesiveFT.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.lshift.net/news/rabbitmqacquired.html&quot;&gt;Read the full story&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>LShift</name>
			<uri>http://www.lshift.net/blog</uri>
		</author>
		<source>
			<title type="html">LShift Ltd.</title>
			<subtitle type="html">What happens at LShift</subtitle>
			<link rel="self" href="http://www.lshift.net/blog/feed/"/>
			<id>http://www.lshift.net/blog/feed/</id>
			<updated>2010-07-16T15:45:37+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">RabbitMQ acquired by SpringSource/VMWare</title>
		<link href="http://erlanginside.com/rabbitmq-acquired-springsource-vmware-162"/>
		<id>http://erlanginside.com/?p=162</id>
		<updated>2010-04-13T13:45:55+00:00</updated>
		<content type="html">Erlang-based RabbitMQ was acquired today by SpringSource...</content>
		<author>
			<name>Chad DePue</name>
			<uri>http://erlanginside.com</uri>
		</author>
		<source>
			<title type="html">Erlang Inside</title>
			<subtitle type="html">News and Information on Erlang and Concurrent Computing</subtitle>
			<link rel="self" href="http://erlanginside.com/feed/atom"/>
			<id>http://erlanginside.com/feed/atom</id>
			<updated>2010-07-22T13:31:03+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">12 April 2010: Erlang Solutions and Quviq Cement Partnership to Deliver Test Driven Development to the Market</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1148"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1148</id>
		<updated>2010-04-12T11:15:51+00:00</updated>
		<content type="html">Erlang Solutions and &lt;a href=&quot;http://www.quviq.com/&quot; target=&quot;_blank&quot;&gt;Quviq AB&lt;/a&gt;, makers of the widely-adopted Quickcheck software tools, announce the formation of a partnership to deliver Quickcheck-based software tools and support services to the enterprise market. Erlang Solutions will be able to offer the full range of Quickcheck products and services to their enterprise clients. Quickcheck, is uniquely designed to test products and services that require high quality and reliability as well as an automated process. &lt;br /&gt;&lt;br /&gt;The partnership formalises Erlang Solutions ability to provide the market with training, consultancy and support for the Quickcheck product portfolio that today covers Erlang and C based solutions.&lt;br /&gt;&lt;br /&gt;</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-07-30T06:15:46+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Slides: Real time Web Application with XMPP and Wave</title>
		<link href="http://www.process-one.net/en/blogs/article/slides_real_time_web_application_with_xmpp_and_wave/"/>
		<id>tag:process-one.net,2010:en/blogs/3.2550</id>
		<updated>2010-04-07T16:30:33+00:00</updated>
		<content type="html">&lt;p&gt;This is the slides of the talk I have given at Erlang Factory 2010 event in San Francisco.&lt;/p&gt; &lt;p&gt;Here are the slides of my presentation on XMPP and our implementation of Wave protocol:&lt;/p&gt;
&lt;div id=&quot;__ss_3658058&quot;&gt;&lt;strong&gt;&lt;a href=&quot;http://www.slideshare.net/mremond/real-time-web-application-with-xmpp-and-wave&quot; title=&quot;Real time Web Application with XMPP and Wave&quot;&gt;Real time Web Application with XMPP and Wave&lt;/a&gt;&lt;/strong&gt; 






&lt;div&gt;View more &lt;a href=&quot;http://www.slideshare.net/&quot;&gt;presentations&lt;/a&gt; from &lt;a href=&quot;http://www.slideshare.net/mremond&quot;&gt;Micka&amp;euml;l R&amp;eacute;mond&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Next blog post will present a screencast of the federation demonstration between our OneWave server and Google Sandbox.&lt;/p&gt;</content>
		<author>
			<name>Mickaël Rémond</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:07:05</id>
			<updated>2010-07-05T20:46:26+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry>
		<title type="html">Dusty Old Projects: Erlang/Dojo Settlers of Catan</title>
		<link href="http://concise-software.blogspot.com/2010/04/dusty-old-projects-erlangdojo-settlers.html"/>
		<id>tag:blogger.com,1999:blog-1172307519118716047.post-1725131886762901187</id>
		<updated>2010-04-07T16:36:57+00:00</updated>
		<content type="html">&lt;p&gt;
A couple of years ago I got it in my head that I should write a Settlers of Catan clone with an Erlang server and a Dojo Toolkit client.  I got fairly far with it, but the rubber never hit the road.  Instead of letting the experience, the bruises and the documents generated from that go to waste I have made all available on Github at &lt;a href=&quot;http://github.com/AlainODea/erlang_dojo_settlers&quot;&gt;http://github.com/AlainODea/erlang_dojo_settlers&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
I think this is a worthwhile project to look at to see the first intuitions of an experienced Java developer attempting to build a system in Erlang.  Particularly the heavy use of processes as objects of a sort.  It also makes some interesting use of JavaScript and The Dojo Toolkit as well.
&lt;/p&gt;
&lt;p&gt;Enjoy :)&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/1172307519118716047-1725131886762901187?l=concise-software.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Alain O'Dea</name>
			<email>noreply@blogger.com</email>
			<uri>http://concise-software.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">In Search of Concise Software</title>
			<subtitle type="html">A journey to find those pieces of software or technology that facilitate productive and maintainable software development</subtitle>
			<link rel="self" href="http://concise-software.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-1172307519118716047</id>
			<updated>2010-07-29T12:31:16+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Enabling SyntaxHighlighter in Blogger Step-by-Step</title>
		<link href="http://concise-software.blogspot.com/2010/03/enabling-syntaxhighlighter-in-blogger.html"/>
		<id>tag:blogger.com,1999:blog-1172307519118716047.post-1991711775710674062</id>
		<updated>2010-04-07T07:06:06+00:00</updated>
		<content type="html">&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://alexgorbatchev.com/wiki/SyntaxHighlighter:Usage&quot;&gt;Learn about SyntaxHighlighter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Layout&lt;/strong&gt; from you Blogger Dashboard&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Edit HTML&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Immediately after &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;, add the following code:
&lt;pre name=&quot;code&quot; class=&quot;brush: html&quot;&gt;
&amp;lt;script src=&amp;#x27;http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shCore.js&amp;#x27; type=&amp;#x27;text/javascript&amp;#x27;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&amp;#x27;http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushErlang.js&amp;#x27; type=&amp;#x27;text/javascript&amp;#x27;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&amp;#x27;http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushXml.js&amp;#x27; type=&amp;#x27;text/javascript&amp;#x27;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;link href=&amp;#x27;http://alexgorbatchev.com/pub/sh/2.1.364/styles/styles/shCore.css&amp;#x27; rel=&amp;#x27;stylesheet&amp;#x27; type=&amp;#x27;text/css&amp;#x27; /&amp;gt;
&amp;lt;link href=&amp;#x27;http://alexgorbatchev.com/pub/sh/2.1.364/styles/shThemeDefault.css&amp;#x27; rel=&amp;#x27;stylesheet&amp;#x27; type=&amp;#x27;text/css&amp;#x27; /&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Save Template&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Page Elements&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Add a Gadget&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;HTML/JavaScript&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;In the &lt;em&gt;Title&lt;/em&gt; field, enter &lt;code&gt;SyntaxHighlighter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Content&lt;/strong&gt; box enter the following code:
&lt;pre name=&quot;code&quot; class=&quot;brush: html&quot;&gt;
&amp;lt;script class='javascript'&amp;gt;//&amp;lt;![CDATA[
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/2.1.364/scripts/clipboard.swf';
SyntaxHighlighter.all();
//]]&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Save&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Edit HTML&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Make note of the &lt;em&gt;widget id&lt;/em&gt; of the &lt;code&gt;b:widget&lt;/code&gt; whose &lt;em&gt;title&lt;/em&gt; is &lt;code&gt;SyntaxHighlighter&lt;/code&gt; (for me it was &lt;code&gt;HTML1&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Immediately before &lt;code&gt;]]&amp;gt;&amp;lt;/b:skin&amp;gt;&lt;/code&gt;, add the following code (with your widget id in place of &lt;code&gt;HTML1&lt;/code&gt;):
&lt;pre name=&quot;code&quot; class=&quot;brush: css&quot;&gt;
#HTML1 {
display:none;
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Save Template&lt;/strong&gt; (this step hides the unnecessary visible gadget from your readers)&lt;/li&gt;
&lt;li&gt;Enjoy syntax highlighting :)&lt;/li&gt;
&lt;/ol&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/1172307519118716047-1991711775710674062?l=concise-software.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Alain O'Dea</name>
			<email>noreply@blogger.com</email>
			<uri>http://concise-software.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">In Search of Concise Software</title>
			<subtitle type="html">A journey to find those pieces of software or technology that facilitate productive and maintainable software development</subtitle>
			<link rel="self" href="http://concise-software.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-1172307519118716047</id>
			<updated>2010-07-29T12:31:16+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Erlang.org traffic no longer exponential</title>
		<link href="http://ulf.wiger.net/weblog/2010/04/05/erlang-org-traffic-no-longer-exponential/"/>
		<id>http://ulf.wiger.net/weblog/?p=184</id>
		<updated>2010-04-05T11:00:07+00:00</updated>
		<content type="html">&lt;p&gt;Bjarne Däcker, who has been tracking download and web site statistics on erlang.org for years, just produced a new graphic.&lt;/p&gt;
&lt;div id=&quot;attachment_185&quot; class=&quot;wp-caption alignnone&quot;&gt;&lt;a href=&quot;http://ulf.wiger.net/weblog/wp-content/uploads/2010/04/erlang-org-traffic-jan10.gif&quot;&gt;&lt;img src=&quot;http://ulf.wiger.net/weblog/wp-content/uploads/2010/04/erlang-org-traffic-jan10-300x225.gif&quot; alt=&quot;Visits to http://www.erlang.org up to March 2010&quot; title=&quot;erlang-org-traffic-jan10&quot; width=&quot;300&quot; height=&quot;225&quot; class=&quot;size-medium wp-image-185&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Visits to http://www.erlang.org up to March 2010&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;For years, the erlang.org graph has been nicely exponential. This latest peak seems to break the pattern. It will be interesting to see what follows.&lt;/p&gt;
&lt;p&gt;(Update: Looking closer at the graph, it appears to stretch as far as to March 2010. I changed the caption, but left the URL unchanged.)&lt;/p&gt;
&lt;p&gt;(Update 2: Closer inspection suggests that this is indeed measurement error. Google analytics, which also takes mirrors into account, reports a steady, but decidedly less dramatic, rise. The number of visitors to &lt;a href=&quot;http://www.erlang.org&quot;&gt;erlang.org&lt;/a&gt; is now at ca 80,000/month, up from ca 57,000/month in September 2008.)&lt;/p&gt;</content>
		<author>
			<name>Ulf Wiger</name>
			<uri>http://ulf.wiger.net/weblog</uri>
		</author>
		<source>
			<title type="html">Ulf Wiger</title>
			<subtitle type="html">CTO Erlang Solutions Ltd - @uwiger - ulf.wiger (at) erlang-solutions.com</subtitle>
			<link rel="self" href="http://ulf.wiger.net/weblog/feed/"/>
			<id>http://ulf.wiger.net/weblog/feed/</id>
			<updated>2010-04-07T08:30:32+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">New Strategic Guide released: from Real-time to Interpersonal Web</title>
		<link href="http://www.process-one.net/en/blogs/article/new_strategic_guide_released_from_real-time_to_interpersonal_web/"/>
		<id>tag:process-one.net,2010:en/blogs/3.2530</id>
		<updated>2010-04-01T13:22:03+00:00</updated>
		<content type="html">&lt;p&gt;ProcessOne has just released a new strategic guide explaining the underlying trends of the web evolution and how this will lead to the interpersonal web, the core business of ProcessOne.&lt;/p&gt; &lt;p&gt;Instant messaging has grown so rapidly in popularity and usage that it is shaping the next era in the evolution of the Internet. This Strategic Guide explains how demand for more real-time communication and personalized content is leading to the emergence of the Interpersonal Web.&lt;/p&gt;
&lt;p&gt;The reference document is published on IMtrends: &lt;a href=&quot;http://www.process-one.net/en/imtrends/article/strategic_guide_the_interpersonal_web/&quot;&gt;Strategic  Guide: The Interpersonal Web&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Further articles with explain how to build this Interpersonal web thanks to ProcessOne technologies.&lt;/p&gt;
&lt;p&gt;Your comments are welcome.&lt;/p&gt;</content>
		<author>
			<name>Mickaël Rémond</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:07:05</id>
			<updated>2010-07-05T20:46:26+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry>
		<title type="html">Is this stupid? Drop Last Element of Erlang List</title>
		<link href="http://concise-software.blogspot.com/2010/03/is-this-stupid-drop-last-element-of.html"/>
		<id>tag:blogger.com,1999:blog-1172307519118716047.post-5389645336025718715</id>
		<updated>2010-03-30T16:38:18+00:00</updated>
		<content type="html">&lt;p&gt;I wanted to drop the last element of a list.  I didn't want a queue, I simply wanted to remove the last character of a string.  Specifically I wanted to remove the &lt;code&gt;\n&lt;/code&gt; from &lt;code&gt;ref: refs/heads/master\n&lt;/code&gt; that comes back when reading the &lt;code&gt;.git/HEAD&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Code listing for &lt;code&gt;trim.erl&lt;/code&gt; module:
&lt;pre name=&quot;code&quot; class=&quot;brush: erlang&quot;&gt;
-module(trim).

-export([string_strip_right/1, reverse_tl_reverse/1, bench/0]).

bench() -&gt; [nbench(N) || N - [1,1000,1000000]].

nbench(N) -&gt; {N, bench([&quot;a&quot; || _ - lists:seq(1,N)])}.

bench(String) -&gt;
    {{string_strip_right,
    lists:sum([
        element(1, timer:tc(trim, string_strip_right, [String]))
        || _ - lists:seq(1,1000)])},
    {reverse_tl_reverse,
    lists:sum([
        element(1, timer:tc(trim, reverse_tl_reverse, [String]))
        || _ - lists:seq(1,1000)])}}.

string_strip_right(String) -&gt; string:strip(String, right, $\n).

reverse_tl_reverse(String) -&gt;
    lists:reverse(tl(lists:reverse(String))).
&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;Benchmark transcript:
&lt;pre&gt;Erlang R13B04 (erts-5.7.5) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.5  (abort with ^G)
1&gt; trim:bench().
[{1,{{string_strip_right,11261},{reverse_tl_reverse,1000}}},
  {1000,
    {{string_strip_right,55131},{reverse_tl_reverse,17915}}},
  {1000000,
    {{string_strip_right,79881856},                                  
     {reverse_tl_reverse,119920353}}}]
2&gt; 
&lt;/pre&gt;&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/1172307519118716047-5389645336025718715?l=concise-software.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Alain O'Dea</name>
			<email>noreply@blogger.com</email>
			<uri>http://concise-software.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">In Search of Concise Software</title>
			<subtitle type="html">A journey to find those pieces of software or technology that facilitate productive and maintainable software development</subtitle>
			<link rel="self" href="http://concise-software.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-1172307519118716047</id>
			<updated>2010-07-29T12:31:16+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">&amp;#8220;Erlang the Movie&amp;#8221; Poster</title>
		<link href="http://steve.vinoski.net/blog/2010/03/29/erlang-the-movie-poster/"/>
		<id>http://steve.vinoski.net/blog/?p=597</id>
		<updated>2010-03-29T16:47:44+00:00</updated>
		<content type="html">&lt;p&gt;They handed out this poster at &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010&quot;&gt;Erlang Factory&lt;/a&gt;. Brilliant!&lt;br /&gt;&lt;center&gt;&lt;img src=&quot;http://steve.vinoski.net/Erlang-the-Movie.jpg&quot; alt=&quot;Erlang the Movie&quot; width=&quot;500&quot; height=&quot;700&quot; /&gt;&lt;/center&gt;&lt;/p&gt;</content>
		<author>
			<name>steve</name>
			<uri>http://steve.vinoski.net/blog</uri>
		</author>
		<source>
			<title type="html">Steve Vinoski's Blog</title>
			<subtitle type="html">Ask forgiveness, not permission.</subtitle>
			<link rel="self" href="http://steve.vinoski.net/blog/feed/atom/"/>
			<id>http://steve.vinoski.net/blog/feed/atom/</id>
			<updated>2010-07-17T18:15:19+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Domain Services and Bounded Context using Akka - Part 2</title>
		<link href="http://debasishg.blogspot.com/2010/03/domain-services-and-bounded-context.html"/>
		<id>tag:blogger.com,1999:blog-22587889.post-700639271219659307</id>
		<updated>2010-03-29T13:43:32+00:00</updated>
		<content type="html">In &lt;a href=&quot;http://debasishg.blogspot.com/2010/03/thinking-asynchronous-domain-modeling.html&quot;&gt;Part 1&lt;/a&gt; of this series you saw how we can model a domain repository as an actor in Akka. It gives you declarative transaction semantics through Akka's STM and pluggable persistence engine support over a variety of data stores. As a result the domain model becomes cleaner. The repository that you design can take advantage of Akka's fault tolerance capabilities through supervisors that offer configurable lifecycle strategies. &lt;br /&gt;&lt;br /&gt;One other important artifact of a domain model are the domain services. A domain service is not necessarily focused on any particular entity and is mostly centered around the verbs of the system. It models some actions or use cases involving multiple entities and is usually implemented as a stateless abstraction.&lt;br /&gt;&lt;br /&gt;Using Akka you model a service as yet another actor. Domain services are coarse level abstractions and are the ones to receive requests from the clients. It can invoke other services or use any other entitites to do the job that it's supposed to do. No wonder a busy service gets requests from lots of consumers. Not only does it need to be stable, but it needs to ensure that all of it's other services with which it collaborates also stay alive while serving requests.&lt;br /&gt;&lt;br /&gt;One of the services that it interacts with is the Domain Repository, which I discussed in the last post.&lt;br /&gt;&lt;br /&gt;When you design a domain service using Akka actors, you can ensure that the service can make its collaborating services fault-tolerant through declarative or minimal programming effort. Akka runtime offers all the machinery to make implementation of fault tolerant services quite easy.&lt;br /&gt;&lt;br /&gt;Consider the following domain service for management of Accounts, continuing our earlier example from the last post ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;trait&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;AccountServer&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Actor&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;handle&amp;nbsp;crash&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;faultHandler&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;OneForOneStrategy&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;trapExit&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;classOf&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;abstract&amp;nbsp;val&amp;nbsp;:&amp;nbsp;the&amp;nbsp;Repository&amp;nbsp;Service&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;storage&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;AccountRepository&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;message&amp;nbsp;handler&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;receive&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Open&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;name&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;storage&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;New&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;name&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Calendar&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;getTime&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;msg&amp;nbsp;@&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Balance&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;storage&amp;nbsp;forward&amp;nbsp;msg&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;msg&amp;nbsp;@&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;_&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;storage&amp;nbsp;forward&amp;nbsp;msg&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;msg&amp;nbsp;@&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;OpenM&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;storage&amp;nbsp;forward&amp;nbsp;msg&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;shutdown&amp;nbsp;hook&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;override&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;shutdown&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unlink&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;storage&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;storage&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;stop&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The message handler is a standard one that forwards client requests to the repository. Note tha use of the abstract &lt;code&gt;val storage: AccountRepository&lt;/code&gt; that helps you defer committing to the concrete implementation class till instantiation of the service object.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;AccountServer&lt;/code&gt; plays the role of a supervisor for the repository actor. The first 2 lines of code defines the strategy of supervision. &lt;code&gt;OneForOneStrategy&lt;/code&gt; says that &lt;i&gt;only the component that has crashed&lt;/i&gt; will be restarted. You can make it &lt;code&gt;AllForOne&lt;/code&gt; also when the supervising actor will restart &lt;i&gt;all of the actors&lt;/i&gt; that it's supervising if one of them crashes. &lt;code&gt;trapExit&lt;/code&gt; defines the list of exceptions in the linked actor for which the supervising actor will take an action.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;AccountServer&lt;/code&gt; is the aupervising actor for the repository. When it is shutdown it has to be unlinked fro the linked actors. This we do in the shutdown hook of the &lt;code&gt;AccountServer&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;But how do we link the Repository actor to our domain service actor ? Note that &lt;code&gt;AccountServer&lt;/code&gt; is not a concrete object yet. We need to instantiate a concrete implementation of &lt;code&gt;AccountRepository&lt;/code&gt; and assign it to storage in &lt;code&gt;AccountServer&lt;/code&gt;. And link the two during this instantiation.&lt;br /&gt;&lt;br /&gt;We define another trait that resolves the abstract val that we defined in &lt;code&gt;AccountServer&lt;/code&gt; and provides a concrete instance of &lt;code&gt;AccountRepository&lt;/code&gt;. spawnLink not only starts an instance of Redis based repository implementation, it also links the repository actor with the &lt;code&gt;AccountServer&lt;/code&gt; ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;trait&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;RedisAccountRepositoryFactory&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Actor&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;storage&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;AccountRepository&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;spawnLink&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;classOf&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;RedisAccountRepository&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Now we have all the components needed to instantiate a fault tolerant domain service object. &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;AccountService&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;AccountServer&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;RedisAccountRepositoryFactory&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;start&amp;nbsp;the&amp;nbsp;service&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;override&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;start&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Actor&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;start&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;RemoteNode&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;9999&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;RemoteNode&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;&amp;quot;account:service&amp;quot;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Have a look at the start method that starts the service on a remote node. We start a remote node and then register the current service under the id &lt;b&gt;&quot;account:service&quot;&lt;/b&gt;. Any client that needs to use the service can get hold of the service actor by specifying this id .. as in the following snippet ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;AccountClient&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;client&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Actor&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Sender&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;service&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;RemoteClient&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;actorFor&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;&amp;quot;account:service&amp;quot;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;9999&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;open&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;name&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;service&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Open&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;name&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;balance&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;service&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;!!&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Balance&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;getOrElse&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;throw&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;&amp;quot;cannot&amp;nbsp;get&amp;nbsp;balance&amp;nbsp;from&amp;nbsp;server&amp;quot;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;post&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;amount&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;service&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;amount&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;openMulti&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)])&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;service&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;!!!&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;OpenMulti&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Services defined using Akka can be made to run on remote nodes without much of an engineering hack. Akka runtime offers APIs for doing that. However, Akka never tries to hide from you the paradigms of distribution. You need to be aware of your distribution requirements and process and supervising hierarchies. Akka facilitates you to define them at the application level, doing the heavy lifting within its underlying implementation. This principle is inspired from Erlang's philosophy and is in sharp contrast to the RPC way of defining APIs. Along with the benefits of message based computation that decouples the sender and the receiver, Akka also enables you to handle states using its built-in STM and pluggable storage engine.&lt;br /&gt;&lt;br /&gt;When you model a complex domain, you need to deal with multiple contexts, which Eric calls &lt;i&gt;Bounded Context&lt;/i&gt;s. Within a specific context you have a cohesive model with a set of domain behavior and abstractions. The interpretations of the same abstractions may change when you move to a different context within the same application. As a domain modeler you need to define your context boundaries very carefully using context maps and implement appropriate translation maps between multiple contexts.&lt;br /&gt;&lt;br /&gt;Messaging is a great way to implement translation between contexts. You process messages within a context using domain services as above and at the end forward the same message or a translated one to the other contexts of the application. It can be in the form of push or you can also implement a publish/subscribe model between the related contexts. In the latter case, you use &lt;a href=&quot;http://doc.akkasource.org/camel&quot;&gt;Akka-Camel integration&lt;/a&gt; that allows actors to send or receive messages through Camel end-points. In either case Akka provides you a world of options to implement loosely coupled domain contexts that form the components of your domain model.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/22587889-700639271219659307?l=debasishg.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Debasish</name>
			<email>ghosh.debasish@gmail.com</email>
			<uri>http://debasishg.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Ruminations of a Programmer</title>
			<subtitle type="html">A programmer's blog - will deal with everything that relates to a programmer. Occasionally, it will contain some humour, some politics and some sport news.</subtitle>
			<link rel="self" href="http://debasishg.blogspot.com/feeds/posts/default?alt=rss"/>
			<id>tag:blogger.com,1999:blog-22587889</id>
			<updated>2010-07-22T07:00:03+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">On the limits of concurrency: Worker Pools in Erlang</title>
		<link href="http://www.lshift.net/blog/2010/03/29/on-the-limits-of-concurrency-worker-pools-in-erlang"/>
		<id>http://www.lshift.net/blog/?p=485</id>
		<updated>2010-03-29T09:35:18+00:00</updated>
		<content type="html">&lt;p&gt;A worker pool is a very common pattern, and they exist in the standard libraries for many languages. The idea is simple: submit some sort of closure to a service which commits to running the closure in the future in some thread. Normally the work is shared out among many different threads and in the absence of anything fancier, one assumes a first-come-first-served queue of closures.&lt;/p&gt;

&lt;p&gt;Erlang, with its light-weight process model is not a language which you would expect would require such an approach: processes are dirt cheap, and the scheduler maps processes onto threads when they are ready to be run &amp;#8212; in many ways, the ErlangVM is a glorified implementation of a worker pool, only one that does pre-emption and other fancy features, in a very similar way to an OS kernel. However, we recently found in RabbitMQ a need for a worker pool.&lt;span id=&quot;more-485&quot;&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;At various points in RabbitMQ, we use mnesia transactions to ensure that state that is held by mnesia (for example, the existence or otherwise of a queue) is updated safely. A client recently informed us that he was creating 10,000 connections, each connection was creating a queue, with exclusive set (which means the queue must be deleted automatically when the connection disappears), and then dropping all the connections at the same time. RabbitMQ would become very unresponsive, for a very very long time. A small amount of head scratching and some quick testing led to the conclusion that this was creating 10,000 transactions, all on the same table, all of which were continuously colliding with each other and thus having to be restarted. Here, the realisation is that there is frequently no good reason to allow more mnesia transactions to go on at the same time than you have cores available &amp;#8212; the probability of a collision will rise exponentially with the number of concurrently in flight transactions.&lt;/p&gt;

&lt;p&gt;The solution here is to submit all of these transactions to a worker pool which has the same number of workers as there are CPU cores in the system. As a result, the probability of a collision is greatly reduced, and things progress much much faster. In many ways, this is a good example of where hinting to the underlying VM as to how it should schedule different jobs would result in massively improved performance.&lt;/p&gt;

&lt;p&gt;One interesting gotcha with this solution is the issue of nested transactions. Mnesia handles these very well indeed, but if we wrap every transaction in a submission to the worker pool, we stop mnesia from knowing that these transactions are nested (which means we lose the unrolling of the inner ones if the outer one subsequently fails), and furthermore, we risk deadlock if every worker in the pool is waiting on another nested transaction to complete. To solve this problem, on submission of a closure, we detect whether or not we are already in a worker pool process, and if we are, we just run the closure in the current process without submission at all. This means that nested transactions are correctly run in the same process as their parent, and we don&amp;#8217;t reach deadlock.&lt;/p&gt;

&lt;p&gt;The code is already QA&amp;#8217;d and merged into our &lt;a href=&quot;http://hg.rabbitmq.com/rabbitmq-server/file/default/&quot;&gt;default branch&lt;/a&gt; and is in the three modules &lt;a href=&quot;http://hg.rabbitmq.com/rabbitmq-server/file/default/src/worker_pool_sup.erl&quot;&gt;worker_pool_sup&lt;/a&gt; (which is the module you just need to start up, it&amp;#8217;ll then start everything else), &lt;a href=&quot;http://hg.rabbitmq.com/rabbitmq-server/file/default/src/worker_pool_worker.erl&quot;&gt;worker_pool_worker&lt;/a&gt; (the actual workers who do the, erm, work), and &lt;a href=&quot;http://hg.rabbitmq.com/rabbitmq-server/file/default/src/worker_pool.erl&quot;&gt;worker_pool&lt;/a&gt; (which is the module to which you submit your jobs). Note that the submission is synchronous, thus you will be returned the result of your closures. Furthermore, your closures are responsible for catching any errors that might occur and returning them to you as values. Finally, note that you&amp;#8217;ll also need our &lt;a href=&quot;http://hg.rabbitmq.com/rabbitmq-server/file/default/src/gen_server2.erl&quot;&gt;gen_server2&lt;/a&gt; module as the worker_pool and worker_pool_worker modules both use this.&lt;/p&gt;</content>
		<author>
			<name>LShift</name>
			<uri>http://www.lshift.net/blog</uri>
		</author>
		<source>
			<title type="html">LShift Ltd.</title>
			<subtitle type="html">What happens at LShift</subtitle>
			<link rel="self" href="http://www.lshift.net/blog/feed/"/>
			<id>http://www.lshift.net/blog/feed/</id>
			<updated>2010-07-16T15:45:37+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Erlang Factory: You Should&amp;#8217;ve Been There</title>
		<link href="http://steve.vinoski.net/blog/2010/03/28/erlang-factory-you-should-have-been-there/"/>
		<id>http://steve.vinoski.net/blog/?p=572</id>
		<updated>2010-03-29T03:44:23+00:00</updated>
		<content type="html">&lt;p&gt;The &lt;a href=&quot;http://www.erlang-factory.com/&quot;&gt;Erlang Factory&lt;/a&gt; &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010&quot;&gt;SF Bay Area 2010&lt;/a&gt; conference just wrapped up last Friday, and it was fantastic. The talks were of high quality and the conference organization was excellent. The slides for all the talks should be on the &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010&quot;&gt;Erlang Factory site&lt;/a&gt; soon.&lt;/p&gt;
&lt;p&gt;If you missed this one, I strongly encourage you to attend the &lt;a href=&quot;http://www.erlang-factory.com/conference/London2010&quot;&gt;London Erlang Factory coming up in June&lt;/a&gt; if you can.&lt;/p&gt;</content>
		<author>
			<name>steve</name>
			<uri>http://steve.vinoski.net/blog</uri>
		</author>
		<source>
			<title type="html">Steve Vinoski's Blog</title>
			<subtitle type="html">Ask forgiveness, not permission.</subtitle>
			<link rel="self" href="http://steve.vinoski.net/blog/feed/atom/"/>
			<id>http://steve.vinoski.net/blog/feed/atom/</id>
			<updated>2010-07-17T18:15:19+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Concise HOWTO's: Message from Erlang to Java</title>
		<link href="http://concise-software.blogspot.com/2009/08/concise-howtos-message-from-erlang-to.html"/>
		<id>tag:blogger.com,1999:blog-1172307519118716047.post-5676133526631977746</id>
		<updated>2010-03-26T17:46:02+00:00</updated>
		<content type="html">&lt;p&gt;First create an EchoServer in Java that receives messages in the format &lt;code&gt;{Sender,Data}&lt;/code&gt; and echoes the &lt;code&gt;Data&lt;/code&gt; portion back to the &lt;code&gt;Sender&lt;/code&gt;.  You will need  &lt;code&gt;OtpErlang.jar&lt;/code&gt; in your build classpath and runtime classpath.  I found it in &lt;code&gt;/opt/local/lib/erlang/lib/jinterface-1.5.1/priv/&lt;/code&gt; on Mac OS X. I had to &lt;a href=&quot;http://concise-software.blogspot.com/2009/08/concise-howtos-install-erlangotp-r13b01.html&quot;&gt;install Erlang from source on Ubuntu&lt;/a&gt; since the APT package is missing Jinterface.&lt;/p&gt;

&lt;h3&gt;Listing for EchoServer.java:&lt;/h3&gt;
&lt;pre name=&quot;code&quot; class=&quot;brush: java&quot;&gt; 
import com.ericsson.otp.erlang.*;

public class EchoServer {
    public static void main(String[] args) throws Exception {
        OtpNode node = new OtpNode(&quot;java&quot;);
        OtpMbox mbox = node.createMbox(&quot;echo&quot;);
        OtpErlangAtom SHUTDOWN = new OtpErlangAtom(&quot;shutdown&quot;);
        while (true) {
            OtpErlangObject message = mbox.receive();
            System.out.format(&quot;%s received: %s%n&quot;, mbox.self(), message);
            if (SHUTDOWN.equals(message)) {
                System.out.format(&quot;%s shutting down...%n&quot;, mbox.self());
                break;
            } else if (message instanceof OtpErlangTuple) {
                OtpErlangTuple messageTuple = (OtpErlangTuple) message;
                if (messageTuple.arity() == 2 &amp;amp;&amp;amp; messageTuple.elementAt(0) instanceof OtpErlangPid) {
                    OtpErlangPid sender = (OtpErlangPid) messageTuple.elementAt(0);
                    OtpErlangObject sendersMessage = messageTuple.elementAt(1);
                    mbox.send(sender, sendersMessage);
                }
            }
        }
    }
}
&lt;/pre&gt;

&lt;p&gt;Once you have compiled and started the EchoServer you can communicate with it from the Erlang shell.  First you need to start a new named node with &lt;code&gt;erl -sname erl_node&lt;/code&gt;.

&lt;h3&gt;Listing of the Erlang shell interaction:&lt;/h3&gt;
&lt;pre&gt;
Erlang R13B01 (erts-5.7.2) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.2  (abort with ^G)
(erl_node@alains_desktop)1&gt; net_adm:ping(java@alains_desktop).                   
pong
(erl_node@alains_desktop)2&gt; {echo,java@alains_desktop} ! {self(),&quot;Hello, Java!&quot;}.
{0.39.0&gt;,&quot;Hello, Java!&quot;}
(erl_node@alains_desktop)3&gt; % use f(M) to &quot;forget&quot; M (make it unbound)
(erl_node@alains_desktop)3&gt; f(M), receive M -&gt; {ok,M} after 100 -&gt; {error,timeout} end.
{ok,&quot;Hello, Java!&quot;}
(erl_node@alains_desktop)4&gt; {echo,java@alains_desktop} ! {self(),{tuples,can,be,sent,too}}.
{0.39.0&gt;,{tuples,can,be,sent,too}}
(erl_node@alains_desktop)5&gt; f(M), receive M -&gt; {ok,M} after 100 -&gt; {error,timeout} end.
{ok,{tuples,can,be,sent,too}}
(erl_node@alains_desktop)6&gt; {echo,java@alains_desktop} ! shutdown.
(erl_node@alains_desktop)6&gt;
(erl_node@alains_desktop)7&gt; {echo,java@alains_desktop} ! shutdown.                         
shutdown
(erl_node@alains_desktop)8&gt; {echo,java@alains_desktop} ! {self(),&quot;Are you there?&quot;}.        
{0.39.0&gt;,&quot;Are you there?&quot;}
(erl_node@alains_desktop)9&gt; f(),receive M -&gt; {ok,M} after 100 -&gt; {error,timeout} end.
{error,timeout}
(erl_node@alains_desktop)10&gt;
&lt;/pre&gt;




&lt;h3&gt;Listing of EchoServer Java process output:&lt;/h3&gt;
&lt;pre&gt;
#Pid received: {#Pid,&quot;Hello, Java!&quot;}
#Pid received: {#Pid,{tuples,can,be,sent,too}}
#Pid received: shutdown
#Pid shutting down...
&lt;/pre&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/1172307519118716047-5676133526631977746?l=concise-software.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;/p&gt;</content>
		<author>
			<name>Alain O'Dea</name>
			<email>noreply@blogger.com</email>
			<uri>http://concise-software.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">In Search of Concise Software</title>
			<subtitle type="html">A journey to find those pieces of software or technology that facilitate productive and maintainable software development</subtitle>
			<link rel="self" href="http://concise-software.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-1172307519118716047</id>
			<updated>2010-07-29T12:31:16+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Concise HOWTOS: Install Erlang/OTP R13B01 from Source on Ubuntu 9.04</title>
		<link href="http://concise-software.blogspot.com/2009/08/concise-howtos-install-erlangotp-r13b01.html"/>
		<id>tag:blogger.com,1999:blog-1172307519118716047.post-2623538214645370129</id>
		<updated>2010-03-26T17:42:44+00:00</updated>
		<content type="html">&lt;p&gt;Generally it is better to use packages, so why have this HOWTO? Ubuntu 9.04's Erlang package is missing Jinterface, but it works when you build Erlang from source.  Debian or Ubuntu will address this omission at some point.  Until then we can build and install the latest Erlang release fairly easily.&lt;/p&gt;

&lt;p&gt;The only real frustration in building from source is making sure all of the necessary build dependencies are installed first.  Well, it also takes a significant chunk of time to build...&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;brush: bash&quot;&gt;
sudo apt-get install build-essential libncurses-dev \
                     unixodbc-dev libssl-dev \
                     libwxgtk2.8-dev default-jdk
curl http://erlang.org/download/otp_src_R13B01.tar.gz
tar xzvf otp_src_R13B01.tar.gz
cd otp_src_R13B01/
./configure
make
sudo make install&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;make&lt;/code&gt; step takes a long time.  It made me really appreciate the pre-built packages I can get so easily and quickly with APT.&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/1172307519118716047-2623538214645370129?l=concise-software.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Alain O'Dea</name>
			<email>noreply@blogger.com</email>
			<uri>http://concise-software.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">In Search of Concise Software</title>
			<subtitle type="html">A journey to find those pieces of software or technology that facilitate productive and maintainable software development</subtitle>
			<link rel="self" href="http://concise-software.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-1172307519118716047</id>
			<updated>2010-07-29T12:31:16+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Concise HOWTO's: Message from Java to Erlang</title>
		<link href="http://concise-software.blogspot.com/2009/08/concise-howtos-message-from-java-to.html"/>
		<id>tag:blogger.com,1999:blog-1172307519118716047.post-6782605412690330731</id>
		<updated>2010-03-26T17:41:51+00:00</updated>
		<content type="html">&lt;p&gt;First create an Erlang module called &lt;code&gt;server&lt;/code&gt; that receives messages in the format &lt;code&gt;{Sender,Data}&lt;/code&gt; and echoes the &lt;code&gt;Data&lt;/code&gt; portion back to the &lt;code&gt;Sender&lt;/code&gt;. Then create a Java class called &lt;code&gt;EchoClient&lt;/code&gt; that prompts for a node to connect to and prompts in a loop for messages to send.  You will need OtpErlang.jar in your build classpath and runtime classpath. I found it in /opt/local/lib/erlang/lib/jinterface-1.5.1/priv/ on Mac OS X. I had to install Erlang from source on Ubuntu since the APT package is missing Jinterface.&lt;/p&gt;

&lt;h3&gt;Listing of &lt;code&gt;server.erl&lt;/code&gt;:&lt;/h3&gt;
&lt;pre name=&quot;code&quot; class=&quot;brush: erlang&quot;&gt;
-module(server).
-compile(export_all).

start() -&gt; register(server,spawn(fun loop/0)).
loop() -&gt;
    receive
        {Sender,Data} -&gt;
            Sender ! Data,
            loop();
        shutdown -&gt; ok
    end.
&lt;/pre&gt;

&lt;h3&gt;Listing of &lt;code&gt;EchoClient.java&lt;/code&gt;&lt;/h3&gt;
&lt;pre name=&quot;code&quot; class=&quot;brush: java&quot;&gt;
import java.io.BufferedReader;
import java.io.InputStreamReader;

import com.ericsson.otp.erlang.*;

public class EchoClient {
    public static void main(String[] args) throws Exception {
        OtpNode node = new OtpNode(&quot;java&quot;);
        OtpMbox mbox = node.createMbox(&quot;admin_gui&quot;);
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String defaultServerNodeName = &quot;erl_node@&quot; + node.host();
        System.out.format(&quot;Server Node to contact [%s]&gt; &quot;, defaultServerNodeName);
        String serverNodeName = in.readLine();
        if (serverNodeName == null || &quot;&quot;.equals(serverNodeName)) {
            serverNodeName = defaultServerNodeName;
        }
        OtpErlangTuple serverPidTuple = new OtpErlangTuple(new OtpErlangObject[] {
                new OtpErlangAtom(&quot;server&quot;), new OtpErlangAtom(serverNodeName)});
        while (true) {
            if (!node.ping(serverNodeName, 1000)) {
                System.out.println(&quot;Erlang node is not available: &quot; + serverNodeName);
                System.exit(1);
            }
            System.out.print(&quot;Message (Hit Enter to send)&gt; &quot;);
            String message = in.readLine();
            if (message != null) {
                mbox.send(&quot;server&quot;, serverNodeName, new OtpErlangTuple(
                        new OtpErlangObject[] {
                                mbox.self(), new OtpErlangList(message)}));
                OtpErlangObject serverReply = mbox.receive(1000);
                if (serverReply == null) {
                    System.out.println(&quot;WARN: Timeout when receiving reply&quot;);
                } else {
                    System.out.format(&quot;%s replied : %s%n&quot;, serverPidTuple, serverReply);
                }
            }
        }
    }
}
&lt;/pre&gt;

&lt;p&gt;Open an Erlang shell in the directory with &lt;code&gt;server.erl&lt;/code&gt; by running &lt;code&gt;erl -sname erl_node&lt;/code&gt;.  From that shell compile and run the Erlang &lt;code&gt;server&lt;/code&gt; module.&lt;/p&gt;

&lt;h3&gt;Listing of the Erlang shell interaction&lt;/h3&gt;
&lt;pre&gt;
$&gt; erl -sname erl_node
Erlang R13B01 (erts-5.7.2) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.2  (abort with ^G)
(erl_node@alains_desktop)1&gt; server:start().
true
(erl_node@alains_desktop)2&gt; server ! {self(), hello}.
{0.84.0&gt;,hello}
(erl_node@alains_desktop)3&gt; f(M), receive M -&gt; {ok, M} after 100 -&gt; {error,timeout} end.
{ok,hello}
(erl_node@alains_desktop)4&gt;
&lt;/pre&gt;

&lt;p&gt;Run the &lt;code&gt;EchoClient&lt;/code&gt; Java program and either accept the default node or specify the name of another Erlang node you want to work with.  Type messages in and see them echoed back to the &lt;code&gt;EchoClient&lt;/code&gt; console.&lt;/p&gt;

&lt;h3&gt;Listing of the &lt;code&gt;EchoClient&lt;/code&gt; Java program console interaction:&lt;/h3&gt;
&lt;pre&gt;
Server Node to contact [erl_node@alains_desktop]&gt; [ENTER]
Message (Hit Enter to send)&gt; Hello, Erlang![ENTER]
{server,erl_node@alains_desktop} replied : &quot;Hello, Erlang!&quot;
Message (Hit Enter to send)&gt;
&lt;/pre&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/1172307519118716047-6782605412690330731?l=concise-software.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Alain O'Dea</name>
			<email>noreply@blogger.com</email>
			<uri>http://concise-software.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">In Search of Concise Software</title>
			<subtitle type="html">A journey to find those pieces of software or technology that facilitate productive and maintainable software development</subtitle>
			<link rel="self" href="http://concise-software.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-1172307519118716047</id>
			<updated>2010-07-29T12:31:16+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">OneTeam Media Server by ProcessOne</title>
		<link href="http://www.process-one.net/en/blogs/article/oneteam_media_server_by_processone/"/>
		<id>tag:process-one.net,2010:en/blogs/3.2517</id>
		<updated>2010-03-26T10:48:36+00:00</updated>
		<content type="html">&lt;p&gt;ProcessOne has just released OneTeam Media Server, a Flash server  written  in erlang.&lt;/p&gt; &lt;p&gt;OneTeam Media Server, or OMS for short, is a new Flash server  implementation, written in erlang, by ProcessOne. This will enable your  users to broadcast voice and/or video streams to multiple subscribers.&lt;/p&gt;
&lt;p&gt;OneTeam Media Server, although being at an early stage, behaves  already quite well, since it is more scalable than &lt;a href=&quot;http://www.red5.org/&quot;&gt;red5&lt;/a&gt;. It might not  be a fair comparison though, since it OMS is not as featurefull as  red5.&lt;/p&gt;
&lt;p&gt;Key features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Support for streaming live/recorded content&lt;/li&gt;
&lt;li&gt;Support for recording live content&lt;/li&gt;
&lt;li&gt;Support for ActionScript3.0 Shared Objects&lt;/li&gt;
&lt;li&gt;Clustering support&lt;/li&gt;
&lt;li&gt;Ability to write application modules in Erlang/OTP&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It still does not include RTMPT for HTTP tunneling. The license  chosen for OneTeam Media Server is the Erlang Public License version  1.1. OMS needs Erlang/OTP R11B-0 or higher.&lt;/p&gt;
&lt;p&gt;The source code is available here: &lt;a href=&quot;https://git.process-one.net/oms&quot;&gt;https://git.process-one.net/oms&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To pull the source code form git, please type:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre&gt;git clone git:&lt;span&gt;//git.process-one.net/oms/mainline.git&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The usual procedure is required (./configure, make, sudo make  install). To start OMS, just type:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre&gt;omsctl start&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Please check the documentation in:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre&gt;doc/doc.html&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;</content>
		<author>
			<name>Nicolas Vérité</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:07:05</id>
			<updated>2010-07-05T20:46:26+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry>
		<title type="html">Replication</title>
		<link href="http://damienkatz.net/2010/03/replication.html"/>
		<id>tag:damienkatz.net,2010://1.559</id>
		<updated>2010-03-23T21:57:07+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;&lt;span class=&quot;mt-enclosure mt-enclosure-image&quot;&gt;&lt;img alt=&quot;bucksfurniturewarehouse40_400.gif&quot; src=&quot;http://damienkatz.net/pics/bucksfurniturewarehouse40_400.gif&quot; width=&quot;400&quot; height=&quot;306&quot; class=&quot;mt-image-none&quot; /&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Some cool Apache CouchDB replication related links:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://blog.couch.io/post/468392274/whats-new-in-apache-couchdb-0-11-part-three&quot;&gt;What's new in Apache CouchDB 0.11 -- Part Three: Replication&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://japhr.blogspot.com/2010/03/extreme-couchdb-replication.html&quot;&gt;Extreme CouchDB Replication&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://books.couchdb.org/relax/reference/clustering&quot;&gt;CouchDB Clustering&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-07-29T19:01:22+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">The fine art of holding a file descriptor</title>
		<link href="http://www.lshift.net/blog/2010/03/23/the-fine-art-of-holding-a-file-descriptor"/>
		<id>http://www.lshift.net/blog/?p=482</id>
		<updated>2010-03-23T17:26:56+00:00</updated>
		<content type="html">&lt;p&gt;People tend to like certain software packages to be scalable. This can have a number of different meanings but mostly it means that as you throw more work at the program, it may require some more resources, in terms of memory or CPU, but it nevertheless just keeps on working. Strangely enough, it&amp;#8217;s fairly difficult to achieve this with finite resources. With things like memory, the classical hierarchy applies: as you use up more and more faster memory, you start to spill to slower memory &amp;#8212; i.e. spilling to disk. The assumption tends to be that one always has enough disk space.&lt;/p&gt;

&lt;p&gt;Other resources are even more limited, and are harder to manage. One of these is file descriptors.&lt;span id=&quot;more-482&quot;&gt;&lt;/span&gt; This is especially difficult to manage in a VM such as Erlang&amp;#8217;s where lots of other systems are potentially using file descriptors and you have no control over them. In the released versions of Rabbit, Rabbit&amp;#8217;s persister used only one or two file descriptors, and the queues themselves used none. This would be an obvious scalability issue in that it would restrict to a single process access to messages stored on disk, were it not for the fact that released versions of Rabbit hold all messages in memory all the time, thus negating that problem (at the expense of a larger scalability issue). However the upside is that as more queues appear, you don&amp;#8217;t need more file descriptors, so almost all file descriptors could be set aside for network sockets. If you need to allow more network connections to Rabbit than your OS provides, then just raise the ulimit (and often the default Erlang process limit too) and away you go.&lt;/p&gt;

&lt;p&gt;With the new persister, each queue requires at least two file descriptors each, and can use a number of file descriptors bounded only by the number of messages stored on disk. Whilst this has removed all sorts of bottlenecks, it has also made the probability of running out of file descriptors rather higher. Introducing a central file descriptor allocator would reintroduce a bottleneck that we have sought to avoid, and so we have developed an alternative scheme for managing file descriptors. This scheme &lt;strong&gt;can&lt;/strong&gt; go wrong: it is really only probabilistic that it works. But, given the way in which Rabbit works, it seems to be working very successfully.&lt;/p&gt;

&lt;p&gt;Firstly, there is a central process. However, this is never &lt;em&gt;asked&lt;/em&gt; for a file descriptor, instead all processes who open files asynchronously tell the central process that they&amp;#8217;ve opened a file. They also tell the central process when they close a file descriptor. With both of these messages, processes include another piece of information which is the time at which the &lt;em&gt;least recently used&lt;/em&gt; file descriptor that the process has open was used. Thus the processes maintain a mapping from file descriptor to the timestamp at which they were last used. The smallest value in this mapping is the value which is included with these messages to the central process. Whenever a process uses a file descriptor, it takes a new timestamp and updates this mapping. No communication is made to the central process on use of a file descriptor.&lt;/p&gt;

&lt;p&gt;The central process detects the ulimit imposed by the OS on the number of file descriptors that can be opened. It imposes an artificial limit, 100 less than the real limit. This gives both buffer space, and allows the rest of the Erlang VM some file descriptors beyond our own control. When we reach this artificial lower limit, the central process does the following calculation: for every process that has some open files, it finds the difference between the current timestamp and the most recently reported &lt;em&gt;least recently used&lt;/em&gt; file descriptor timestamp. It sums and averages these ages to give the average time since the &lt;em&gt;least recently used&lt;/em&gt; file descriptors were used. It then asynchronously sends messages to all the processes with open files, telling them to close any file descriptor that has not been used for more than this average time.&lt;/p&gt;

&lt;p&gt;The first time the processes receive this message, they may very well find that they don&amp;#8217;t have any file descriptors that have not been used for this long. This is because the central process is only informed or processes&amp;#8217; &lt;em&gt;least recently used&lt;/em&gt; file descriptor timestamps &lt;em&gt;when the process opens or closes a file descriptor&lt;/em&gt;. As such, if the process then uses the file descriptor then the central process will immediately have out of date information. Thus all processes, when they receive a request to close files descriptors older than the calculated average, they always inform the central process of the timestamp of their current &lt;em&gt;least recently used&lt;/em&gt; file descriptor. Thus at this point, the central process is brought up to date, and if it finds that it&amp;#8217;s still at or over the limit of open file descriptors, it recalculates the average age (which will now be less than before) and asks all the processes again to close file descriptors older than the new, smaller average age.&lt;/p&gt;

&lt;p&gt;What this means is that processes are never blocked from opening files, even when Rabbit&amp;#8217;s over the limit of file descriptors. However, immediately after opening a file, when it goes to receive its next message, a process may find a request from the central process, asking it to close the file it&amp;#8217;s just opened. Thus the limit is enforced softly, in a way which does as little as possible to impact performance. This is the reason why we have the lower artificial limit: to try and guard against the possibility of lots of processes opening files at the same time, pushing us over the limit before they or any other process receive the close request from the central process. However it can still go wrong: if a process is hell bent on opening as many files as possible then it can do so, and still hit the hard OS limit, crashing the VM. Cooperation from the processes is obviously vital: for example if a process can never open more than one file descriptor before checking its mailbox again, then you&amp;#8217;re very likely to be safe in this scheme.&lt;/p&gt;

&lt;p&gt;All of this is implemented in a module called &lt;a href=&quot;http://hg.rabbitmq.com/rabbitmq-server/file/bug21673/src/file_handle_cache.erl&quot;&gt;file_handle_cache.erl&lt;/a&gt; which is available in the new persister branch of RabbitMQ. This module also wraps many of the functions of Erlang&amp;#8217;s file module, providing many more optimisations (at the cost of, for example, only ever being able to append to files). These optimisations aim to reduce to an absolute minimum the number of OS calls. So, much better control of write buffers is provided, and seeks which would position the file handle at the same location as it currently is are optimised out. Further calls are provided, e.g. to throw away the write buffer contents without writing them out to disk.&lt;/p&gt;

&lt;p&gt;When the request to close a file comes in, the &lt;a href=&quot;http://hg.rabbitmq.com/rabbitmq-server/file/bug21673/src/file_handle_cache.erl&quot;&gt;file_handle_cache&lt;/a&gt; module works out which file descriptors to close. If it finds a file handle to close, it flushes any outstanding writes, closes the file, but keeps track of the last state that it was in. Thus the next time the process decides to use that file descriptor, the module can silently reopen the file and seek to the last location. As a result, when writing to this module, you never need to find out whether or not the central process has asked the module to close files and what, if anything, the result of that request was. The result is a system which dynamically closes old and unused file descriptors but without imposing arduous constraints on the client: the module manages all the state of the file descriptors.&lt;/p&gt;

&lt;p&gt;Finally, there are some file descriptors which we have decided, after careful consideration, not to arbitrarily close. These are network sockets to AMQP clients. For these, it is indeed right to have a central process controlling whether further sockets can be created. This is simply implemented as a pair of synchronous calls (acquire and release) to the central process which lowers and raises, respectively, the artificial limit on the number of allowed file descriptors.&lt;/p&gt;</content>
		<author>
			<name>LShift</name>
			<uri>http://www.lshift.net/blog</uri>
		</author>
		<source>
			<title type="html">LShift Ltd.</title>
			<subtitle type="html">What happens at LShift</subtitle>
			<link rel="self" href="http://www.lshift.net/blog/feed/"/>
			<id>http://www.lshift.net/blog/feed/</id>
			<updated>2010-07-16T15:45:37+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">StarCraft2 AI Coding</title>
		<link href="http://feedproxy.google.com/~r/curious-attempt-bunny/~3/evmHgjs_1xA/starcraft2-ai-coding.html"/>
		<id>tag:blogger.com,1999:blog-3376508392331888241.post-9184803088100171584</id>
		<updated>2010-03-22T11:28:40+00:00</updated>
		<content type="html">So I was curious as to how come the StarCrack AI folks are finding it so easy to develop new and improved AI for StarCraft 2. It turns out that there's an SC2Data file that's an mpq archive. So I downloaded their AI distribution and extracted their code. The first thing I noticed is that there's more than AI in here, there's actual game balancing information. E.g.:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&amp;lt;CWeaponLegacy id=&quot;Marauder&quot;&gt;&lt;br /&gt;  &amp;lt;EditorCategories value=&quot;Race:Terran&quot;/&gt;&lt;br /&gt;  &amp;lt;DisplayEffect value=&quot;MarauderU&quot;/&gt;&lt;br /&gt;  &amp;lt;DisplayAttackCount value=&quot;1&quot;/&gt;&lt;br /&gt;  &amp;lt;TargetFilters value=&quot;Ground,Visible;Missile,Stasis,Dead,Hidden,Invulnerable&quot;/&gt;&lt;br /&gt;  &amp;lt;Range value=&quot;6&quot;/&gt;&lt;br /&gt;  &amp;lt;Period value=&quot;1.5&quot;/&gt;&lt;br /&gt;  &amp;lt;DamagePoint value=&quot;0&quot;/&gt;&lt;br /&gt;  &amp;lt;Backswing value=&quot;0&quot;/&gt;&lt;br /&gt;  &amp;lt;Effect value=&quot;MarauderLM&quot;/&gt;&lt;br /&gt;  &amp;lt;Icon value=&quot;Assets\Textures\btn-upgrade-terran-infantryweaponslevel1.dds&quot;/&gt;&lt;br /&gt;&amp;lt;/CWeaponLegacy&gt;&lt;/pre&gt;&lt;/code&gt;That makes me wonder if it's possible to edit these files in order to artificially make an opposing race harder or easier to play against.&lt;br /&gt;&lt;br /&gt;Looking at the contents of TriggerLibs, this all looks very much like C code. Sweet. My next thought is that this can probably be translated into one big Groovy script without too much hassle, and then these StarCrack folks could write test harnesses! It must be a real pain to have to crank up StarCraft itself to see if you coded the right thing. I don't see all the TriggerDebugOutput logging as being a good substitute.&lt;br /&gt;&lt;br /&gt;Edit: I gave this a quick stab. The first real problem with this idea is that there are multiple declarations of the method InitCounters.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3376508392331888241-9184803088100171584?l=curious-attempt-bunny.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/curious-attempt-bunny/~4/evmHgjs_1xA&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>Curious Attempt Bunny</name>
			<email>noreply@blogger.com</email>
			<uri>http://curious-attempt-bunny.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">curious-attempt-bunny</title>
			<subtitle type="html">Inquisitive guinea pig =&gt;
neugieriges Versuchskaninschen =&gt; curious attemptbunny</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/curious-attempt-bunny"/>
			<id>tag:blogger.com,1999:blog-3376508392331888241</id>
			<updated>2010-07-24T18:45:43+00:00</updated>
		</source>
	</entry>

</feed>
