Archive for February, 2011

Using Distributed Caching With Agatha

7 commentsWritten on February 27th, 2011 by
Categories: agatha

As you may or may not know, Agatha has supported server-side caching of responses for a while now (it also sports built-in client-side caching actually). But it only came with one in-memory implementation of that cache. And while that implementation works well, it's still just an in-process cache which just isn't sufficient for some scenarios.

This week i was introduced to Membase, a great distributed caching solution which is very easy to set up. I wanted to see what it would take to make Agatha's server-side caching work with Membase. With a little help from the Enyim Membase client, it turned out to be very easy. If you want to change the actual caching implementation that Agatha uses, you have to implement 2 interfaces. First, you'll need a custom implementation of the ICache interface:

    public class MembaseCache : ICache
    {
        private readonly MembaseClient membaseClient;

        public MembaseCache(string region = null)
        {
            // this implementation assumes password-less buckets
            membaseClient = new MembaseClient(region, null);
        }

        public Response GetCachedResponseFor(Request request)
        {
            return membaseClient.Get<Response>(GetKey(request));
        }

        public void Store(Request request, Response response, TimeSpan expiration)
        {
            membaseClient.Store(StoreMode.Set, GetKey(request), response, expiration);
        }

        public void Clear()
        {
            membaseClient.FlushAll();
        }

        private static string GetKey(Request request)
        {
            return string.Format("{0}_{1}", request.GetType().FullName, request.GetHashCode());
        }
    }

With Agatha's caching, you can use regions in your caching configuration. A region corresponds with a bucket in Membase. If you don't specify a region name when configuring caching for a response, Agatha will use the default region which is named _defaultRegion. You will need to create at least the _defaultRegion bucket in your Membase cluster, and you'll also need to create a bucket for each other region you use in your caching configuration. When your service layer is initialized, Agatha will create an ICache instance for each known region to be used.

Then you'll need an ICacheProvider implementation:

    public class MembaseCacheProvider : ICacheProvider
    {
        public ICache BuildCache(string region)
        {
            return new MembaseCache(region);
        }
    }

Now, because the Enyim Membase client uses binary serialization of cached objects by default, we're going to provide our own ITranscoder (defined in the Enyim assembly) implementation which uses the DataContractSerializer:

    public class MembaseTranscoder : ITranscoder
    {
        public CacheItem Serialize(object o)
        {
            using (var stream = new MemoryStream())
            {
                var serializer = new DataContractSerializer(typeof(Response), KnownTypeProvider.GetKnownTypes(null));
                serializer.WriteObject(stream, o);
                var data = stream.ToArray();

                return new CacheItem(((ushort)(((ushort)Type.GetTypeCode(o.GetType())) | 0x100)),
                    new ArraySegment<byte>(data, 0, data.Length));
            }
        }

        public object Deserialize(CacheItem item)
        {
            using (var stream = new MemoryStream(item.Data.Array.Skip(item.Data.Offset).ToArray()))
            {
                var serializer = new DataContractSerializer(typeof(Response), KnownTypeProvider.GetKnownTypes(null));
                return serializer.ReadObject(stream);
            }
        }
    }

That's actually all we need to support distributed response caching with Membase. To use this, you'd need to add this to the configuration file of your service host:

  <membase>
    <servers bucket="_defaultRegion">
      <add uri="http://localhost:8091/pools/default" />
    </servers>
    <transcoder type="Agatha.Common.Caching.MembaseTranscoder, Agatha.Common" />
  </membase>

Obviously, you'd need a bucket definition for every region that you'd use and you'll probably need a different bucket URI as well ;)

You'd also need to configure Agatha to use the MembaseCacheProvider implemention:

            var config = new ServiceLayerConfiguration(Assembly.GetExecutingAssembly(), 
                typeof(HelloWorldRequest).Assembly, typeof(Agatha.Castle.Container))
                            {
                                CacheProviderImplementation = typeof(MembaseCacheProvider)
                            };
            config.Initialize();

And that's it... distributed caching of service-layer responses has never been this easy ;)

Note that i haven't committed this implementation to Agatha's Subversion repository... the plan is to add it in the 2.0 version, which will have many more changes (more on that in a future post). But if you need it already, or you need inspiration for an implementation that targets a different distributed caching server, the information in this post should get you going.

Recommended Book: HTML5 And CSS3: Develop With Tomorrow’s Standards Today

2 commentsWritten on February 22nd, 2011 by
Categories: Books

Going by the hype surrounding HTML5, you'd think it's all about animations and taking away the need to use proprietary plugins like Flash and Silverlight. But there's plenty more interesting things in HTML5 (or the related technologies) which you can already start using in your web applications. Brian P. Hogan does an excellent job covering a lot of them in this book.

The first chapter gives you a good overview on what exactly HTML5 and CSS3 will allow you to do, and also contains a helpful list of tags and attributes that will be deprecated in the HTML5 specification. After that, the book is split up in 3 larger parts:

  1. Improving User Interfaces
  2. New Sights And Sounds
  3. Beyond HTML5

The first part consists of 4 chapters that cover how you can improve the things that you're already doing with HTML. You'll learn about new structural tags and attributes that help you avoid 'divitis', how you can create much better forms, and a bunch of new CSS selectors that'll make your CSS code much cleaner and easier. Finally, you'll learn more about how to make sure that your pages are accessible to people who require assistive technology to browse your site/webapp. What's really interesting about these chapters is that for each new thing that is discussed, fallback strategies for browsers that don't support the new features are covered as well.

The second part covers the features that most of the hype surrounding HTML5 is based on: drawing on the canvas, embedding audio and video in your pages and some very interesting eye candy features from CSS3 such as rouding corners, drop shadows, element rotation, gradients and the improved font features.

The final part covers some technologies that are often associated with HTML5 but aren't actually part of the specification. Things like client-side storage options, managing browser-history, cross-document messaging, web sockets and geolocation. Each of these are covered with clear examples. The final chapter covers some topics that are likely to change in the near future but it gives you a good idea on what to expect from CSS transitions, web workers, WebGL, IndexedDB, Drag & Drop and client-side validation.

Overall, the quality of writing is excellent, the examples are very clear and despite being a quick read at 231 pages (not counting the appendices) it covers quite a lot of interesting things, most of which you can indeed start using today. This book won't make you an expert on any of the topics it covers though, nor is that its intention. It is a great way to get started with these new features and technologies though, and encourages you to dig deeper.

Intelligent Validation

8 commentsWritten on February 20th, 2011 by
Categories: Off Topic

Btw, anyone know when Resharper 6 final is coming out?

There’s Only One Valid Metric For Developer Productivity And Quality

17 commentsWritten on February 19th, 2011 by
Categories: Code Quality, Opinions, Software Development

Depending on who you ask, software developers have been programming for over 40 to 50 years. And we still have no truly objective way to measure a developer's productivity and quality level. People can think or say that a developer is fast or productive, but they can't truly quantify it. People can think or say that a developer is great, good or bad, but again, they can't truly quantify it with numbers. We often look at other metrics to give us an idea on quality or productivity such as code metrics, or velocity but those numbers often reflect the efforts of a group of people. After all, a codebase is more often the result of the efforts of more than one person, and a team's velocity is typically the result of the productivity of, well, a group of people. Those numbers can't really be used to gain insight to the quality or productivity of a specific developer.

Not only is the current way of trying to determine the productivity or quality of a developer rather subjective, it's quite often based on things that are only one part of the equation: what they did, and the time in which they did it. I've always felt that that only really tells you half the story. I don't hold much value on knowing how long a developer took to write a certain piece of code or to complete a specific feature. I also don't really care a lot about the code metrics for that piece of code or that specific feature. All i know is that it took some effort. The quality or productivity of that effort can't truly be measured without knowing how much extra effort will be introduced later on because of that effort.

Suppose you have 2 developers, John and Sally. You give them both the same task and you tell them that the estimated workload for that task is 12 hours. John completes the task in 10 hours, and Sally needs 14 hours to complete it. It would be easy to think that John is more productive than Sally based on this. Especially if results like those were to repeat quite often. But what if John's solution requires an extra 6 hours of effort down the line to fix some bugs, or because his code was such a mess to follow that it slowed down future tasks which required another developer to comprehend the code of John's task? That would put John's eventual total to 16 hours of effort, instead of the originally reported 10 hours. And what if Sally's solution didn't introduce any future effort whatsoever down the line? Hell, maybe Sally's solution saved someone else an hour here or there because her solution was so easy to comprehend or perhaps even to reuse. Her total for that task remains at 14 while at the same time maybe even reducing future numbers. In this scenario, Sally is clearly a more productive and better programmer than John though we wouldn't know about it if we'd based ourselves on the initial numbers.

Consider another scenario though. John again spends 10 hours on the same task, and Sally again spends 14 hours. John kept it as simple and as straightforward as he could. Hell, he actually took a shortcut or two to finish faster. Sally is an outspoken member of the Software Craftsmanship movement and stays up to date with all of the latest and greatest patterns and approaches that are making their rounds on the internet. Sally spent a little bit of extra effort to make sure the code is as great as it possibly can be. It's incredibly readable and uses a great new pattern that all the cool kids on the internet rave about. The code metrics clearly show that Sally's solution is of a much higher quality. Unfortunately, it turns out that the other team members are having trouble understanding that code and they often lose time trying to figure it out whenever they need to do something which involves that part of the codebase. While Sally may claim that she took more time because she did it 'better', the extra effort wasn't worth it because no matter how well her intentions with that code, it ended up costing other people time. And what if John's shortcuts didn't introduce any future effort?

There are countless variations on this scenario which makes it virtually impossible to come up with a way to measure productivity or quality based on hours spent or code metrics. The only way to objectively measure this is to define a new metric which holds into account the extra effort that will be introduced later on. I'd call this metric Eventual Efficiency. Quality or productivity by themselves don't really mean anything if one influences the other negatively. Efficiency however can be seen as a combination of the two. Did you write truly fantastic code which ended up not mattering at all? Not efficient. Did you write mediocre code that got the job done and didn't (or hardly) introduced future effort? Sounds pretty efficient to me. Did you write great code that reduced future effort? Very efficient! Did you write bad code quickly that ended up introducing a lot of effort? Not efficient at all.

Unfortunately, we'll probably never get to the point where we can actually measure the Eventual Efficiency of developers. Until we do, it's worth keeping in mind that whatever numbers we might be looking at don't really mean anything without the link to the related future effort.

Using Generic TestFixtures To Run Tests In Multiple Browsers With WatiN

6 commentsWritten on February 14th, 2011 by
Categories: testing

Just ran into something that i thought was pretty cool. If you're using WatiN, it's relatively easy to write browser-based automated tests without resorting to recorded tests. And since WatiN supports multiple browsers, you can write those tests in a browser-agnostic manner. And if you make use of NUnit's Generic Fixtures (introduced in NUnit 2.5), you can very easily run those tests in multiple browsers as well. Suppose you have the following base test fixture:

    public abstract class ViewTest<TBrowser> where TBrowser : Browser, new()
    {
        [TestFixtureSetUp]
        public void FixtureSetUp()
        {
            Browser = new TBrowser();
            Browser.GoTo(RootUrl);
        }

        [TestFixtureTearDown]
        public void FixtureTearDown()
        {
            if (Browser != null)
            {
                Browser.Dispose();
            }
        }

        [SetUp]
        public void SetUp()
        {
            DoSetUp();
        }

        protected TBrowser Browser { get; private set; }

        protected string RootUrl { get { return ConfigurationManager.AppSettings["RootUrl"]; } }

        protected virtual void DoSetUp() { }
    }

You can then write a test fixture like this:

    [TestFixture(typeof(IE))]
    [TestFixture(typeof(FireFox))]
    public class ListCustomersTests<TBrowser> : ViewTest<TBrowser> where TBrowser : Browser, new()
    {
        protected override void DoSetUp()
        {
            Browser.GoTo(RootUrl + "Customers");
        }

        [Test]
        public void ShowsErrorMessageWhenClickingProceedWithoutSelectingAnItemFromGrid()
        {
            var proceedButton = Browser.Button(button => button.Value == "Proceed");
            Assert.IsFalse(Browser.Para("selection_required").Exists);
            proceedButton.Click();
            Assert.That(Browser.Para("selection_required").Exists);
        }
    }

And when you run your tests, it will run this test once in IE, and once in Firefox.

Resharper's TestRunner has issues with this though... it does run the tests, but it doesn't report any feedback on them. The normal NUnit testrunner does show the feedback correctly though.