Sunday 22 July 2012

Cache Fluffer / Gorilla Caching / Cache Warmer

The relatively simple introduction of a cache fluffer can make a huge difference to performance, particularly at peak load. The idea is simple, keep the cache up to do date so you don't have to go and get data when the user requests the site.

        public T Get(Func<T> factory, string cacheKey)
        {
            if (cache.Contains(cacheKey))
            {
                Task.Factory.StartNew(() => FluffTheCache(factory, cacheKey));
                return cache.Get(cacheKey);
            }
            return Put(factory, cacheKey);
        }

        public void FluffTheCache(Func<T> factory, string cacheKey)
        {
            var expiry = cache.getExpiry(cacheKey);
            if (expiry.Subtract(new TimeSpan(0, 0, 10)).Second < new Random().Next(1, 60))
            {
                Put(factory, cacheKey);
            }
        }

        public T Put(Func<T> factory, string cacheKey)
        {
            var item = factory();
            cache.Set(item, cacheKey);
            return item;
        }
The beauty with this method is that popular items will always be in cache where as less popular items will not be cached for unnecessary lengths of time.

You also get some randomization mixed in for free meaning that items don't come out of sync at the same time.

Tuesday 10 July 2012

Testing Async Behaviour - AutoResetEvent WaitOne

This little nugget helps you test async code.

https://github.com/7digital/SevenDigital.Api.Wrapper/blob/master/src/SevenDigital.Api.Wrapper.Unit.Tests/FluentAPITests.cs

Essentially you use a semaphore to signal that something has finished. In our case we're using the AutoResetEvent. This allows to wait up to an amount of time for something happen.

In our case we're waiting for an action to be fired and we want to ensure the result is true.

[Test]
public void AsyncTest()
{
  var autoResetEvent = new AutoResetEvent(false);
  new Something.Async(
    action =>
    {
 Assert.That(action.SomethingToTest, Is.True);
 autoResetEvent.Set();
    });

  var result = autoResetEvent.WaitOne(1000 * 60);
  Assert.That(result, Is.True, "Method Not Fired");
}
Make sure that you test the result from WaitOne. If you don't you're not testing that the method actually returns.

Monday 9 July 2012

Samsung Chromebox with XBMC

What to do with a Chromebox?

At google IO 2012 every delegate got a free Samsung Chromebox. Personally I already have a laptop, desktop, tablet and smart phone. Why would I need a cut down desktop? It would probably be great for your Nan who has no idea what they're doing and just wants to email the grandkids.

So what should I do with this piece of hardware? Well my xbox classic is struggling to play some high def media files, it is over 10 years old, how about I use my free chromebox.

Enable Developer Mode

Essentially flip a switch and erase all user data. Here's how.

Install ChrUbuntu

I only had one problem following these instructions, me, I didn't follow them. You must leave your box in developer mode, meaning that boot time takes almost a minute because of the developer mode warning.

Install XBMC

XBMC has been accepted into debian.
sudo apt-get install xbmc
BOOM!

Install VNC and SSH

Invaluable, otherwise you'll be plugging in your keyboard and mouse every time you get a problem. 

Install SSH
Enable Remote Desktop Connections

Run xbmc on startup

I had a slight issue with xbmc starting just before the window manager had fully started. This was causing xbmc to start in a windowed state. Instead I wrote a small script to pause for 2 seconds then start xbmc.

#!/bin/sh
sleep 5
xbmc
chmod +x and then add the file into the script to startup programs.

Summary

In total it took me about 90 minutes. My main annoyance is the beep you get on startup. I connected it to my TV through the dvi port. It handled 720p files with no problems, just need to test with some 1080p files.

Just waiting on my display port -> HDMI cable  so that I can give it a proper testing.

Would I recommend buying one explicitly for this purpose, no, unless the price tag is brought down significantly.