<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>localghost.io</title>
  <subtitle>Love data, design and most of all, the web.</subtitle>
  <link href="https://www.localghost.io/feed.xml" rel="self" />
  <link href="https://www.localghost.io/" rel="alternate" />
  <id>https://www.localghost.io/</id>
  <updated>2013-06-11T08:57:00+02:00</updated>
  <author>
    <name>Martijn Laarman</name>
  </author>
  <entry xml:base="https://www.localghost.io/articles/on-devops-at-a-project-based-shop-2013-06-11/">
    <title>On devops at a project based shop</title>
    <link href="https://www.localghost.io/articles/on-devops-at-a-project-based-shop-2013-06-11/" rel="alternate" />
    <id>https://www.localghost.io/articles/on-devops-at-a-project-based-shop-2013-06-11/</id>
    <published>2013-06-11T08:57:00+02:00</published>
    <updated>2013-06-11T08:57:00+02:00</updated>
    <summary>The term DevOps has many overloaded meanings so let me first state what I think encompasses the term DevOps: everything related to development but not…</summary>
    <content type="html">&lt;p&gt;The term &lt;code&gt;DevOps&lt;/code&gt; has many overloaded meanings so let me first state what I think encompasses the term &lt;code&gt;DevOps&lt;/code&gt;: everything related to development but not directly to implementing the core product/project's functionality.&lt;/p&gt;
&lt;p&gt;More concretely:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Automating the build&lt;/li&gt;
&lt;li&gt;Continuous Builds&lt;/li&gt;
&lt;li&gt;Continuous Integration&lt;/li&gt;
&lt;li&gt;Unit Testing&lt;/li&gt;
&lt;li&gt;Integration Tests&lt;/li&gt;
&lt;li&gt;Continuous Testing&lt;/li&gt;
&lt;li&gt;Automating the deploy procedure&lt;/li&gt;
&lt;li&gt;Package the deploy&lt;/li&gt;
&lt;li&gt;Continuous Deploy&lt;/li&gt;
&lt;li&gt;Centralized error monitoring&lt;/li&gt;
&lt;li&gt;Centralized log inspection&lt;/li&gt;
&lt;li&gt;Centralized machine monitoring&lt;/li&gt;
&lt;li&gt;Custom event monitoring (think statsd)&lt;/li&gt;
&lt;li&gt;Machine provisioning&lt;/li&gt;
&lt;li&gt;Machine configuration automation&lt;/li&gt;
&lt;li&gt;Automating data backups&lt;/li&gt;
&lt;li&gt;Automating data synchronization&lt;/li&gt;
&lt;li&gt;Automating data-store upgrades&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As you can imagine checking every item on this list of quality providing measurements is a massive undertaking. This is usually not scoped in product development let alone in project development. Yet each and everyone of this steps is a huge quality assurance indicator with massive value and if we are to take our trade seriously is something we should all be doing.&lt;/p&gt;
&lt;p&gt;I tend to view this check list as &lt;code&gt;shadow work&lt;/code&gt;: work that is implicitly implied but never explicitly mentioned.&lt;/p&gt;
&lt;p&gt;From what I've seen it's the shops who develop products or maintain a single website tend to do better then project based shops who inherently have shorter development cycles.&lt;/p&gt;
&lt;p&gt;A product shop has a continuous life-cycle which rather non-surprisingly makes way for continuous &lt;code&gt;&amp;lt;anything&amp;gt;&lt;/code&gt; to creep it's way high on the agenda as they start to form obstacles.&lt;/p&gt;
&lt;p&gt;A project shop has a very limited life-cycle, getting something out the door often trumps all and often rightfully so. The rather cruel catch 22 here is that especially these short life-cycle projects benefit the most from the devops checklist. Knowledge of the ins and outs of the moving parts of such a project are lost quickly. All the items on the devops serve as documentation as code and provide a warm welcome back for any developer picking up the project back up after a year or when doing SLA maintenance work.&lt;/p&gt;
&lt;p&gt;Limited life-cycle is only one factor hindering project shops checking items off the devops check list. Having multiple projects means that each project comes with its own set of challenges further complicating the matter.&lt;/p&gt;
&lt;p&gt;At my previous job at a project shop I helped standardize some of the devops check list and there I had the added benefit that all development happened in .NET on windows machines, the websites were hosted on in house windows servers and development happened rather linearly in SVN. This means that solutions for items on the checklist are reusable and learnings from one project can be transfered to the next. As a developer this meant that introducing new moving parts, say an exotic tech-stack is not something you can easily do. Even in this homogeneous development environment getting to check &lt;em&gt;ALL&lt;/em&gt; the items off the list is quite an investment both financially and personally convincing everyone involved of the necessity.&lt;/p&gt;
&lt;p&gt;At my current job at a bigger project shop, that prides itself on using whatever tech stack is best for the project and has quite an agile mindset, development happens on Windows, Linux, OSX machines and projects are hosted on the cloud with Google, Amazon and Microsoft or on private dedicated servers behind weird VPN arrangements and project spans range from 6 weeks to three years. On top of that some releases follow a strict sign off procedure by clients others can be released when we deem necessary. Some development is linear and is easily continuously integrated, some follow a heavy branching model.&lt;/p&gt;
&lt;p&gt;This means that the knowledge on how to implement each item on the devops check list becomes very fragmented based on environment, language and framework choices, development model and release strategies. For an aspect of our profession already not high on the radar for many developers and managers this quickly becomes too much too handle.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;little dirty secret&lt;/strong&gt; in our industry that in a lot of cases devops turns into shadow work at best, done in the spare hours of a project.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;&lt;code&gt;big dirty secret&lt;/code&gt;&lt;/strong&gt; is that in a lot of cases this shadow work is simply ignored. This can have many causes&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Developers are simply unaware of this work&lt;/li&gt;
&lt;li&gt;Developers ignore it because they are time-constraint because this &lt;code&gt;shadow work&lt;/code&gt; is not budgeted for.&lt;/li&gt;
&lt;li&gt;Developers are aware but managers/project leads do not know how to sell this work to the client.&lt;/li&gt;
&lt;li&gt;A client simply refuses to acknowledge the necessity of this &lt;code&gt;shadow work&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think the &lt;code&gt;devops&lt;/code&gt; movement is great and more than just the new hip buzzword as it forces a flashlight onto the &lt;code&gt;shadow work&lt;/code&gt; and gets it on everybody's agenda.&lt;/p&gt;
&lt;p&gt;At &lt;a href="http://www.q42.nl"&gt;@q42&lt;/a&gt; colleague &lt;a href="https://twitter.com/markvanstraten"&gt;Mark van Straten&lt;/a&gt; was given 6 hours a week to improve our devops story and although Mark did an absolutely stellar job getting all the current and past projects to build and deploy automatically we really found that this is not a one man project and 6 hours a week is really not sufficient to take care of ALL the shadow work on the &lt;code&gt;devops checklist&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Having fulfilled a similar role in my previous job Mark and I often debate to &lt;code&gt;How's and Why's&lt;/code&gt; of devops and even-though we disagree sometimes on details we share the greater vision of the importance of this &lt;code&gt;shadow work&lt;/code&gt;. So we recently called a meeting, &lt;code&gt;&amp;lt;insert meeting bashing comment here&amp;gt;&lt;/code&gt; with fellow colleagues who also take an interest and came to the following conclusions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Devops is &lt;strong&gt;NOT&lt;/strong&gt; a one man operation.&lt;/li&gt;
&lt;li&gt;That said a dedicated &lt;code&gt;devop'er&lt;/code&gt; might be a very good idea, not every developer has the time to learn puppet/chef and all the other aspects of the &lt;code&gt;ops&lt;/code&gt; side of things.&lt;/li&gt;
&lt;li&gt;A project technical lead is responsible for getting &lt;code&gt;shadow work&lt;/code&gt; on a project's agenda.&lt;/li&gt;
&lt;li&gt;This can mean that he/she decides not to something on the &lt;code&gt;checklist&lt;/code&gt; for pragmatic reasons.&lt;/li&gt;
&lt;li&gt;Everybody in a team is responsible for actually doing devops work.&lt;/li&gt;
&lt;li&gt;Devops is not just a back-ender's job there's a lot to automate on the front-end too.
&lt;ul&gt;
&lt;li&gt;i.e a JS front-end guy writes scripts and makes sure they can report results in a xunit format so TC knows what it means.&lt;/li&gt;
&lt;li&gt;The CSS guru automates the styleguide generation i.e rendering all the button permutations.&lt;/li&gt;
&lt;li&gt;Writing integration tests in phantomjs&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.gruntjs.com"&gt;GruntJS&lt;/a&gt; all the things!&lt;/li&gt;
&lt;li&gt;etcetera..&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One thing is for sure &lt;code&gt;Devops&lt;/code&gt; work is a constant battle but as long it's a battle we are fighting we're on the right track.&lt;/p&gt;
&lt;p&gt;Do you work for a project shop and are also fighting the &lt;code&gt;shadow work&lt;/code&gt; let me know how you are coping in the comments!&lt;/p&gt;
</content>
  </entry>
  <entry xml:base="https://www.localghost.io/articles/the-joys-of-.net-oss-development-2013-04-03/">
    <title>The joys of .NET OSS development</title>
    <link href="https://www.localghost.io/articles/the-joys-of-.net-oss-development-2013-04-03/" rel="alternate" />
    <id>https://www.localghost.io/articles/the-joys-of-.net-oss-development-2013-04-03/</id>
    <published>2013-04-03T09:33:00+02:00</published>
    <updated>2013-04-03T09:33:00+02:00</updated>
    <summary>Today a quite heated debate opened up on twitter on a number of questions concerning open source development in .NET Doing a full recap of all the points…</summary>
    <content type="html">&lt;p&gt;Today a quite heated debate opened up on twitter on a number of questions concerning open source development in .NET
Doing a full recap of all the points being made would be rather tedious but have a look at &lt;a href="https://www.twitter.com/gblock"&gt;Glenn Block's twitter feed&lt;/a&gt; most of the question and arguments raised boiled down to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Does Microsoft do enough to promote OSS projects?&lt;/li&gt;
&lt;li&gt;Should Microsoft even step up or should the community do more?&lt;/li&gt;
&lt;li&gt;Is there even a OSS .net community?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This also sparked quite an interesting conversation on Jabbr that i sadly just missed out on. I went back to preserve &lt;a href="jabbr-oss-room-convo.html"&gt;the conversation here&lt;/a&gt; if you'd like to read it back. You'll have to scroll down to Wednesday, April 03, 2013, forgive my laziness here.&lt;/p&gt;
&lt;p&gt;I've been running &lt;a href="https://www.github.com/Mpdreamz/NEST"&gt;an open source project&lt;/a&gt; for the past two years with success, I've had many people contribute and submit issues and the project is in use at some great sites out there and I couldn't be happier with the community. The fact remains though that I am still the project's only main maintainer and the only one answering questions on github and stackoverflow.&lt;/p&gt;
&lt;p&gt;The only exposure I get is through making sure my documentation is on par and the project looks like its stable and still maintained when people hit the readme page on github. People have tweeted kind words, like &lt;a href="https://twitter.com/jptoto/status/287329848249167873"&gt;this&lt;/a&gt; or &lt;a href="https://twitter.com/montesinnos/status/318811105478725634"&gt;this&lt;/a&gt;, for which I'm super grateful!, that helps create a possitive buzz when someone googles for a .NET elasticsearch client.&lt;/p&gt;
&lt;p&gt;To be honest though I think this is too be expected and I am OK with this. Unless you are lucky to have someone on board as a second maintainer, opensource means you have to do all the hard work. I don't write code to please Microsoft so I ask for nothing in return. I write code because I need it, I share it so that others may benefit. If enough people do, which I believe to be the case even in the .NET dev world, you get a community going.&lt;/p&gt;
&lt;p&gt;Although I dont expect anything from Microsoft I really &lt;strong&gt;don't&lt;/strong&gt; get anything from Microsoft either. jetBrains donated a free Resharper license, my awesome employer &lt;a href="http://www.q42.nl"&gt;Q42&lt;/a&gt; even donates a day a week of my time to the project.
Microsoft does not hand out MVP's for doing well in opensource, no msdn subscription, no reach outs from community managers.&lt;/p&gt;
&lt;p&gt;To be fair as a community I do think we too can do better, we don't have a go to website everybody goes to for daily updates on whats going on in the .net world. Finding like minded developers is an exercise in who follows who on twitter.&lt;/p&gt;
&lt;p&gt;If we're too thrive as a community doing .NET OSS development it should be despite of Microsoft, not because of it.&lt;/p&gt;
&lt;p&gt;Which is also why I'll refrain from bullet-listing everything Microsoft does wrong..&lt;/p&gt;
&lt;p&gt;As a closing note I like to think if my project, that serves quite a niche, gets so many involved either through raising issues or sending pull requests I am anything but pessimistic about the community. Even if C# is only the 11th most popular language on github.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;Comments from before this blog moved are on &lt;a href="https://github.com/Mpdreamz/localghost.io/issues/5"&gt;this post's GitHub issue&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</content>
  </entry>
  <entry xml:base="https://www.localghost.io/articles/oss-development,-a-continuous-lesson-in-humility-2013-03-07/">
    <title>OSS development, a continuous lesson in humility</title>
    <link href="https://www.localghost.io/articles/oss-development,-a-continuous-lesson-in-humility-2013-03-07/" rel="alternate" />
    <id>https://www.localghost.io/articles/oss-development,-a-continuous-lesson-in-humility-2013-03-07/</id>
    <published>2013-03-07T13:41:00+01:00</published>
    <updated>2013-03-07T13:41:00+01:00</updated>
    <summary>Yesterday I recieved a bug report on NEST, my .net client for elasticsearch. Now I've received many bug reports in the last 2 years and on several occasions…</summary>
    <content type="html">&lt;p&gt;Yesterday I recieved a bug report on &lt;a href="https://github.com/Mpdreamz/NEST"&gt;NEST&lt;/a&gt;, my .net client for elasticsearch. Now I've received many bug reports in the last 2 years and on several occasions these bug reports made me feel humiliated to the bone.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Yes, I wrote that and yes, that's pretty stupid&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now I am only human, my first reaction when I receive a pretty severe bug report is: &lt;code&gt;Surely this can't be true&lt;/code&gt; and &lt;code&gt;Come on! I'm not that stupid!&lt;/code&gt; but 90% of the time I investigate and can only conclude: &lt;code&gt;Yes it IS true&lt;/code&gt; and &lt;code&gt;Yes I AM that stupid&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/Mpdreamz/NEST/issues/189"&gt;Yesterday's bug report&lt;/a&gt;, was a prime example of this.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-markdown"&gt;Async requests are not really async
------
Hi,
I noticed that SearchAsync is making synchronous calls in reality.
I think the fault might be with this code (DoAsyncRequest):

if (tcs.Task != null &amp;amp;&amp;amp; tcs.Task.Result != null)

As it accesses the Task's Result, we wait for the task to complete...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fuck me thats pretty severe! &lt;code&gt;Surely this can't be true&lt;/code&gt; and &lt;code&gt;Come on! I'm not that stupid!&lt;/code&gt; Looking &lt;a href="https://github.com/Mpdreamz/NEST/blob/9aed4e2e90087d2ffb398dc18b68159190f951f3/src/Nest/Domain/Connection/Connection.cs#L156-L167"&gt;at the code&lt;/a&gt; though:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cs"&gt;var tcs = new TaskCompletionSource&amp;lt;ConnectionStatus&amp;gt;();
this.Iterate(this._AsyncSteps(request, tcs, data), tcs);
if (tcs.Task != null &amp;amp;&amp;amp; tcs.Task.Result != null)
{
    tcs.Task.Result.Request = data;
    tcs.Task.Result.RequestUrl = request.RequestUri.ToString();
    tcs.Task.Result.RequestMethod = request.Method;
}
return tcs.Task;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Damnit! &lt;code&gt;Yes it IS true&lt;/code&gt; and &lt;code&gt;Yes I AM that stupid&lt;/code&gt;. Fair enough the fix seems easy enough, return a continuation on the task instead.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cs"&gt;var tcs = new TaskCompletionSource&amp;lt;ConnectionStatus&amp;gt;();
this.Iterate(this._AsyncSteps(request, tcs, data), tcs);
return tcs.Task.ContinueWith(t =&amp;gt;
{
    cs.Task.Result.Request = data;
    tcs.Task.Result.RequestUrl = request.RequestUri.ToString();
    tcs.Task.Result.RequestMethod = request.Method;
    return tcs.Task.Result;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nest's comes with a demo indexer that tests the troughput of the different &lt;code&gt;IConnection&lt;/code&gt; implementations. The code itself looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cs"&gt;var partitionedMessages = msgGenerator.Generate(numMessages).Partition(bufferSize);
Interlocked.Exchange(ref NumSent, 0);
foreach (var messages in partitionedMessages)
{
    var t = client.IndexManyAsync(messages, indexName, bulkParms);
    tasks.Add(t);

    Interlocked.Add(ref NumSent, bufferSize);
    if (NumSent % 10000 == 0)
    {
        Console.WriteLine(&amp;quot;Sent {0:0,0} messages to {1}&amp;quot;, NumSent, indexName);
    }
}
Task.WaitAll(tasks.ToArray());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;msgGenerator&lt;/code&gt; generates &lt;code&gt; new Message()&lt;/code&gt;'s' without doing ANY IO. So I really should be seeing multiple requests being being processed at the same time.&lt;/p&gt;
&lt;p&gt;Yet fiddlers timeline shows me something pretty horrific:&lt;/p&gt;
&lt;p&gt;&lt;img src="fiddlertimelinefirstrun.PNG" alt="fiddler timeline first run" /&gt;&lt;/p&gt;
&lt;p&gt;Somethings still blocking damnit.&lt;/p&gt;
&lt;p&gt;For reference here's the throughput the test app reports:
&lt;img src="consoleoutputfirstrun.PNG" alt="consoleoutputfirstrun" /&gt;&lt;/p&gt;
&lt;p&gt;Fuck me these are not anywhere near the throughput numbers &lt;a href="https://github.com/Mpdreamz/NEST/pull/112#issuecomment-10266029"&gt;I reported 4 months ago&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-markdown"&gt;HTTP: 12123 docs/s
Thrift: 17575 docs/s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mother of regressions!&lt;/p&gt;
&lt;p&gt;Looking at the &lt;code&gt;&amp;quot;fixed code&amp;quot;&lt;/code&gt; again:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cs"&gt;var tcs = new TaskCompletionSource&amp;lt;ConnectionStatus&amp;gt;();
this.Iterate(this._AsyncSteps(request, tcs, data), tcs);
return tcs.Task.ContinueWith(t =&amp;gt;
{
    cs.Task.Result.Request = data;
    tcs.Task.Result.RequestUrl = request.RequestUri.ToString();
    tcs.Task.Result.RequestMethod = request.Method;
    return tcs.Task.Result;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;TaskCompletionSource&lt;/code&gt; still blocks while it coordinates the async steps. Let's try that again:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cs"&gt;var tcs = new TaskCompletionSource&amp;lt;ConnectionStatus&amp;gt;();
if (!this._ResourceLock.WaitOne(timeout))
{
    var m = &amp;quot;Could not start the operation before the timeout of &amp;quot; + timeout + &amp;quot;ms completed while waiting for the semaphore&amp;quot;;
    tcs.SetResult(new ConnectionStatus(new TimeoutException(m)));
    return tcs.Task;
}
try
{
    return Task.Factory.StartNew(() =&amp;gt;
    {
        this.Iterate(this._AsyncSteps(request, tcs, data), tcs);
        return tcs.Task.Result;
    }, TaskCreationOptions.LongRunning);
}
finally
{
    this._ResourceLock.Release();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here I explicitly start a new Task and on top of that moved the semaphore out of &lt;code&gt;_AsyncSteps()&lt;/code&gt; so we delay the creation of &lt;code&gt;Task&amp;lt;T&amp;gt;&lt;/code&gt;'s to the very last second. The &lt;code&gt;TaskCreationOptions.LongRunning&lt;/code&gt; is also key here to prevent threadpool starvation! The TPL will prefer to really start a new Thread for your task not take one from the threadpool.&lt;/p&gt;
&lt;p&gt;Let's see how we are doing now:&lt;/p&gt;
&lt;p&gt;&lt;img src="fiddlertimelinesecondrun.PNG" alt="fiddler timeline second run" /&gt;&lt;/p&gt;
&lt;p&gt;Yes! that's more like it!&lt;/p&gt;
&lt;p&gt;&lt;img src="consoleoutputsecondrun.PNG" alt="consoleoutputsecondrun" /&gt;&lt;/p&gt;
&lt;p&gt;Nice, we actually improved throughput from 12k 4 months ago to 17k now. Awesome!&lt;/p&gt;
&lt;p&gt;This is why developing in the open is so awesome, it keeps you humble and grounded benefiting both your sanity and the quality of the project.&lt;/p&gt;
&lt;p&gt;These fixes are pushed to nuget and in &lt;a href="https://www.nuget.org/packages/Nest"&gt;Nest 0.9.20.0&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;Comments from before this blog moved are on &lt;a href="https://github.com/Mpdreamz/localghost.io/issues/4"&gt;this post's GitHub issue&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</content>
  </entry>
</feed>