3.18.2014

Ax Vestigial Features

I routinely observe projects where developers and users are busy safeguarding countless features that provide absolutely no value to anybody. In many situations people are aware but nobody will do anything about it. In other situations, they may not even know.

Vestigial features sap the efficacy of systems. Take the time to curate metrics to effectively monitor the features of your systems. After a sufficient period of time has elapsed without enough usage to financially justify maintaining a feature, ax it. If your metrics are anywhere close to accurate no one will notice.

Then, take a moment to reflect on how things ended up this way. Was this a feature that outlived its purpose? Or was it something that provided no value to begin with? Tell the story to help others avoid a similar fate.

2.10.2014

Workspace: To sit or to stand

Working at home offers many opportunities to create your ideal work environment. Investing in your dream workspace is a no brainer. With no corporate rules to abide by, why not setup a killer workspace? A central part of this is your desk. Here's how I got started standing... I hope it helps you get started too!

To sit or to stand?

My Current Setup

I noticed after years of full time sitting while working long days, that I just felt lethargic and tired after work. I'd have to go home and take a nap before I could hit the gym or otherwise continue my evening affairs.

After just a few days of standing, I noticed significant improvement in my energy levels. I'm not claiming there's science to back this up, but sitting all day seems to sap my mental and physical energy levels.

Not convinced? There are tons of articles about why sitting is bad for your health

Step 1: Hack a standup desk

At first, I took my desk and stacked books and boxes until my keyboard, mouse and monitors were at a level to allow for standing. The first few days, my legs were sore, but that quickly faded. However, I noticed that standing ALL day was physically exhausting...

Step 2: Try a stool

So, I found a stool that allowed me to alternate between sitting and standing. If you get a stool, make sure you measure the height you'll need, many stools are way too short, be wary of stools under 30 inches. Over the years, I've found it's ideal to try to stand most of the day and use a stool or chair for breaks.

These were some of my favorite stools, except the base breaks down after a few years of heavy use :(

Winsome Wood Air Lift Adjustable Stools

Being height adjustable, I could get the perfect height when I wanted to take a break from standing. They are light and slide out of the way easily when you want to stand.

Step 3: Your feet will thank you... get a great mat to stand on

After a few days of standing I felt like I was killing my feet. I already wear inserts to support my duck like flat feet, but standing on cement, even with carpet, will do a number on your body. I've settled on this mat as my favorite:

Imprint Comfort Mat Nantucket Series 20-Inch by 36-Inch, Cinnamon

  • You can roll it up to travel, great for moving
  • After years of standing on it, it hasn't shown any signs of wear
  • It's wide enough to move around and stay on the mat
  • You can easily slide or throw it out of the way when you want to sit down
  • You can wipe up spills with a rag
  • Lots of sizes and colors

Step 4: Wear shoes when standing

It's tempting, especially when working at home, to just walk around in socks or barefoot. I really feel like I get the best support when I'm wearing shoes AND standing on my mat. If you have inserts for medical reasons, wear those too, oh and if you don't, maybe try some off the shelf supports too.

When you do take a break, kick off the shoes and let your feet breathe!

Step 5: Invest in a height adjustable desk

Although a stool is nice for a break, when I sit, I want to relax. So, I sought a desk to allow me to do both without compromise! Also, I wanted a desk to facilitate alternating sitting and standing without more than a few seconds interruption. Meet GeekDesk.

Recommendations

  • Invest in the large model so you have plenty of workspace, it's less than $50 difference.
    • I've seen many people advocate for a simple hack. If you only have a monitor and keyboard stand, you won't have room for paperwork, laptops, peripherals, inboxes and most importantly, your cup of coffee!
    • Think about what you do with a desk now, would you really be able to give up all that space simply because you are standing?
  • Get the programmable heights feature - GeekDesk Max, you can click a preset height, step back (or get a cup of coffee) and let the desk do the work.
    • If you get the manual adjustment, every time you want to change positions, you'll have to hold the button and remember the height you want and wait as the desk adjusts. As a result of this hassle, you will change positions less often, which will actually be counter productive to the benefits of alternating positions.
  • The desk requires some assembly, no more than 2 hours.
  • Be patient for its arrival, it took several months for mine to arrive, but believe me it's worth the wait! Check their estimated wait times.
  • I've noticed the Beech Veneer picks up stains, maybe consider a darker color, or attach your own top.
  • When you need to get to the back of your computer, just pop the desk up and it's a breeze to get back there!

Get long enough wires

Any wire that runs from the desk to your computer needs to be long enough to support sitting and standing heights. When purchasing new peripherals, consider this, many wires are only about a meter long. I'd say 6 feet is a minimum, 8 is probably preferable, especially if you want the wire to run to the back of the desk, and reach down and over to wherever you place your computer.

A block to stand on

When standing, it's comfortable to alternate one foot on a block to take the weight off of it. A cinder block works great, and if that looks tacky, a sturdy, small safe works great too!

Step 7: The monitors

Sometimes you'll want your monitors at slightly different positions. I don't adjust this every time I change from sitting to standing, but when the situation calls for it, I like to quickly move the monitors. A fixed height monitor is just a bad idea for any desk setup, it will do a number on your neck and posture. I absolutely love the following monitor arms:

LX Desk Mount LCD Arm

  • You can adjust the monitor up, down, left and right, push it back, pull it towards you, tilt it, rotate it and pan!
  • You can accomplish any position you desire
  • And they just STAY where you leave them, magic!

Recommendations

  • Lighter monitors work better, look at LED monitors, avoid LCD
  • Make sure your monitor provides a VESA compliant mount, most do
  • This dell monitor works GREAT if you're looking for a new monitor. 24" 1200p resolution, whereas most 24" monitors are only 1080p, and it's very affordable.

Dell UltraSharp U2412M 24-Inch Screen LED-lit Monitor

Step 8: Location, location, location

Remember you have complete freedom to setup your workspace wherever you want! If you don't like dark dreary places, don't put your desk in a closed off location. I like to put mine next to the window, it's like having that window office the execs get :)

Find the most inspirational place in your home that you can dedicate to your workspace. The location of a home office while you worked in a real office isn't likely the same place you'll want a full time remote work setup. Your needs have changed, consider them!

Stools versus Chairs

Once you have a height adjustable desk, the need for a stool will fade if you already have a great office chair. I'd recommend putting the money towards a better desk in the first place.

Why this matters?

There are many unique challenges to remote work. Creating the ideal workspace is a way to get excited about working at home and to help overcome some of the other challenges.

1.30.2014

Disable encoding with custom html builders in Razor without using IHtmlString

If you use a custom html builder, not marked with IHtmlString, and don't want to use the verbose @Html.Raw(builder) and would rather just use @builder, see this gist for how to set this up:


1.13.2014

Building a mongodb provider for the new ASP.NET Identity framework - Part 1

Microsoft is hard at work on a new ASP.NET Identity framework. I thought it would be fantastic to start working on a mongodb provider. In a series of posts I'll discuss adapting the framework to work with mongodb, the decisions I made and hopefully spark some interest and get some feedback.

I'm not going to spend a lot of time re-hashing the details of the framework, instead here are some links for background:

I setup a nuget package: Install-Package AspNet.Identity.MongoDB -Pre

Designing IdentityUser

One of the first things we need is a model of a user, IUser is the interface we must implement.

Naming it

The first decision I had to make was what to name this thing? I decided to follow the Entity Framework implementation's IdentityUser to make it easier for users to get up and running with the mongo implementation.

String v ObjectId in .net

In the latest pre-release of Microsoft.AspNet.Identity.Core 2.0.0-alpha1, the IUser interface has been updated to support a TKey generic parameter. Prior versions used a string for the user's Id. We could go ahead and use ObjectId for TKey, but to be honest, working with strings in .net applications is often easier, especially when model binding and serializing/deserializing objects. I'm going to stick with string for TKey:

public class IdentityUser : IUser<string>
{
    public string Id { get; private set; }

    public string UserName { get; set; }
}

ObjectId representation in mongo

Even though we're using strings in our application, I want the Id to be stored as an ObjectId. Mongo is optimized to deal with ObjectId and it's much more familiar to people who work with mongodb. To do this I decorated the Id property with a BsonRepresentation attribute:

public class IdentityUser : IUser<string>
{
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; private set; }

    public string UserName { get; set; }
}

Distributed Id generation

The client driver will assign an id if the Id is not set on an insert, but I wanted to save developers the time of waiting until after an insert to get the Id. In the spirit of decentralized creation of ids which is one of many reasons to use a doc db, I setup the IdentityUser type to generate an id whenever it's created. During de-serialization from mongo, this will be overwritten with an actual id when loading existing user documents.

public class IdentityUser : IUser<string>
{
    public IdentityUser()
    {
        Id = ObjectId.GenerateNewId().ToString();
    }

    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; private set; }

    public string UserName { get; set; }
}

Implementing IUserStore

The first service interface to implement in the new identity framework is IUserStore. This provides basic CRUD operations on user storage. In the spirit of keeping with EF naming, I named this UserStore. I created an IdentityContext to decide where users are stored, this may change as I develop the provider, let me know if you have ideas. There are lots of tests of this in the repository, I wrote the majority as integration tests around the UserManager type in the identity framework. UserManager orchestrates using the different identity service interfaces, like IUserStore, to provide a facade to consuming applications and frameworks. Anyways, here is the UserStore:

public class UserStore<TUser> : IUserStore<TUser>
    where TUser : IdentityUser
{
    private readonly IdentityContext _Context;

    public UserStore(IdentityContext context)
    {
        _Context = context;
    }

    public void Dispose()
    {
        // no need to dispose of anything, mongodb handles connection pooling automatically
    }

    public Task CreateAsync(TUser user)
    {
        return Task.Run(() => _Context.Users.Insert(user));
    }

    public Task UpdateAsync(TUser user)
    {
        return Task.Run(() => _Context.Users.Save(user));
    }

    public Task DeleteAsync(TUser user)
    {
        var remove = Query<TUser>.EQ(u => u.Id, user.Id);
        return Task.Run(() => _Context.Users.Remove(remove));
    }

    public Task<TUser> FindByIdAsync(string userId)
    {
        return Task.Run(() => _Context.Users.FindOneByIdAs<TUser>(ObjectId.Parse(userId)));
    }

    public Task<TUser> FindByNameAsync(string userName)
    {
        var byName = Query<TUser>.EQ(u => u.UserName, userName);
        return Task.Run(() => _Context.Users.FindOneAs<TUser>(byName));
    }
}

And here is the IdentityContext:

public class IdentityContext
{
    public MongoCollection Users { get; private set; }

    public IdentityContext(MongoCollection users)
    {
        Users = users;
        EnsureUniqueIndexOnUserName(users);
    }

    private void EnsureUniqueIndexOnUserName(MongoCollection users)
    {
        var userName = new IndexKeysBuilder().Ascending("UserName");
        var unique = new IndexOptionsBuilder().SetUnique(true);
        users.EnsureIndex(userName, unique);
    }
}

The consuming application passes a MongoCollection instance to store users. MongoCollection is thread safe so we're ok to share a single instance of it. The IdentityContext then ensures there is a unique index on the UserName field so we don't get duplicate users! This will create the index if it doesn't exist. This functionality may move at some point, but this seemed like a good place to start.

Extending IdentityUser

Part of the purpose of the new identity framework is to allow users to tack on their own data in a strongly typed fashion. This is where mongo shines, I added tests in EnsureWeCanExtendIdentityUserTests to verify this works, here's how one would do this:

public class ExtendedIdentityUser : IdentityUser
{
    public string MyUserField { get; set; }

    public void MyUserBehavior(){ ... }
}

And to use it:

var context = new IdentityContext(Users);
var userStore = new UserStore<ExtendedIdentityUser>(context);
var userManager = new UserManager<ExtendedIdentityUser>(userStore);

Next

Let me know what you think of the decisions so far. In subsequent posts I'll show how to implement more of the service interfaces and talk about the decisions I encounter. Check out the repository on github, it's full of unit and integration tests.

1.10.2014

C# async/await makes reactive testing expressive!

Isolating asynchronous behavior isn't always possible, especially when it comes to creating integration tests. However, with the new async/await features in c# 5, testing reactive interfaces is a breeze and can be very expressive.

FileSystemWatcher and events

FileSystemWatcher is commonly used to monitor for changes to a directory. It's been around since .Net 1.1. Whenever I work with event based interfaces, I prefer to wrap them with an Observable. Testing this often requires an integration test. Here's some code to convert the FileSystemWatcher.Changed event to an observable:

IObservable<FileSystemEventArgs> Changed = Observable
    .FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(h => Watcher.Changed += h, h => Watcher.Changed -= h)
    .Select(x => x.EventArgs);

I'm using this to create an ObservableFileSystemWatcher adapter. I'll be referring to this in the following tests.

The following code is captured in this gist, look at the revision history to see the changes between each of the following samples.

Designing a test

Historically, testing asynchronous behavior required blocking calls and hackery to capture information for our assertions. Here's how we might be tempted to start testing the observable wrapper:

[Test]
public void WriteToFile_StreamsChanged()
{
    using (var watcher = new ObservableFileSystemWatcher(c => { c.Path = TempPath; }))
    {
        FileSystemEventArgs changed = null;
        watcher.Changed.Subscribe(c =>
        {
            changed = c;
        });
        watcher.Start();

        File.WriteAllText(Path.Combine(TempPath, "Changed.Txt"), "foo");

        Expect(changed.ChangeType, Is.EqualTo(WatcherChangeTypes.Changed));
        Expect(changed.Name, Is.EqualTo("Changed.Txt"));
    }
}

To test the Changed observable, we Subscribe to Changed and then capture the last result into a local changed variable. This way we can run assertions on the changed notification. Next, we Start the watcher, create a new file, and verify we get a notification.

However, when we run this test, it fails. The file notification is asynchronous and thus non-deterministic. We don't know if it will happen before or after our assertions are executed.

Waiting for the result

Historically, we'd have to modify this test to wait for the changed notification. We could use a ManualResetEvent to wait:

[Test]
[Timeout(2000)]
public void WriteToFile_StreamsChanged()
{
    using (var watcher = new ObservableFileSystemWatcher(c => { c.Path = TempPath; }))
    {
        var reset = new ManualResetEvent(false);
        FileSystemEventArgs changed = null;
        watcher.Changed.Subscribe(c =>
        {
            changed = c;
            reset.Set();
        });
        watcher.Start();

        File.WriteAllText(Path.Combine(TempPath, "Changed.Txt"), "foo");

        reset.WaitOne();
        Expect(changed.ChangeType, Is.EqualTo(WatcherChangeTypes.Changed));
        Expect(changed.Name, Is.EqualTo("Changed.Txt"));
    }
}

The reset will block the test at the call to WaitOne just before our assertions. When the changed notification happens, Set will be called in our subscriber and the test will complete. To be safe, the test has also been modified to Timeout after 2 seconds.

Now our test works, but it's not pretty :(

Making it expressive with async/await

Thanks to the new c# 5 async/await language features, we can fix this. Here's the new way we can write this test:

[Test]
[Timeout(2000)]
public async Task WriteToFile_StreamsChanged()
{
    using (var watcher = new ObservableFileSystemWatcher(c => { c.Path = TempPath; }))
    {
        var firstChanged = watcher.Changed.FirstAsync().ToTask();
        watcher.Start();

        File.WriteAllText(Path.Combine(TempPath, "Changed.Txt"), "foo");

        var changed = await firstChanged;
        Expect(changed.ChangeType, Is.EqualTo(WatcherChangeTypes.Changed));
        Expect(changed.Name, Is.EqualTo("Changed.Txt"));
    }
}

Observables are awaitable, which means we can wait (non-blocking) for the next item. In this case, we can use FirstAsync().ToTask() to create a Task, that upon completion, will contain the first result of the observable sequence. This task is named firstChanged above. This task could complete at any time. Of course in this case, nothing will happen until we create the test file. We're free to continue setting up the test as we've already indicated the desire to capture the first result!

Next, we Start the watcher, create the test file and then the magic, we use await to wait for the result of our firstChanged task. Once the task is complete, the changed notification will be captured into our changed variable. I love how readable this is 'changed equals wait for the first changed'! Once the first changed notification arrives, the assertions will run and the test will complete.

Strive for Expressive Tests

The historical strategy works, but the new style is more compact and doesn't require so much brain power to understand. This new style makes this test much easier to write and much easier to maintain. Try this out and see how it improves your own testing, let me know what you come up with!