Protocol Buffers DataReader Extensions for .NET

.NET, as a mostly-statically typed language, has a lot of really good options for serializing statically-typed objects. Protocol Buffers, MessagePack, JSON, BSON, XML, SOAP, and the BCL’s own proprietary binary serialization are all great for CLR objects, where the fields can be determined at runtime.

However, for data that is tabular in nature, there aren’t so many options. In my past two jobs I’ve had a need to serialize data:

  • That is tabular – not necessarily CLR DTOs.
  • Where the schema is unknown before it is deserialized – each data set can have totally different columns.
  • In a way that is streamable, so entire entire data sets do not have to be buffered in memory at once.
  • That can be as large as hundreds of thousands of rows/columns.
  • In a reasonably performant manner.
  • In a way that could potentially be read by different platforms.
  • Into as small a number of bytes as possible.

Protocol Buffers DataReader Extensions for .NET was born out of these needs. It’s powered by Marc Gravell’s excellent Google Protocol Buffers library, protobuf-net, and it packs data faster and smaller than the equivalent DataTable.Save/Write XML:

Usage is very easy. Serializing a data reader to a stream:

DataTable dt = ...;using (Stream stream = File.OpenWrite("C:foo.dat"))using (IDataReader reader = dt.CreateDataReader()){    DataSerializer.Serialize(stream, reader);}

Loading a data table from a stream:

DataTable dt = new DataTable();using (Stream stream = File.OpenRead("C:foo.dat"))using (IDataReader reader = DataSerializer.Deserialize(stream)){    dt.Load(reader);}

It works with IDataReaders, DataTables and DataSets (even nested DataTables). You can download the protobuf-net-data from NuGet, or grab the source from the GitHub project page.

Failing the tube test

As a Londoner working in the city, I (along with hundreds of thousands of others) catch the tube to work every day. Although you’re typically crammed in a carriage with hundreds of other commuters, the journey is a solitary one, and many passengers turn to their iPhones, iPads and Kindles to pass the time.

image

For me, it’s a pretty long journey, up to an hour each way to get from Parsons Green to Canary Wharf — a large portion of which is spent deep underground, with no mobile or 3G coverage on my iPhone 4. During this time you can really tell which apps’ data strategies have been properly thought out and designed, and which ones have been hacked together in a hurry.

I’m not going to mention any offending games or apps by name, but these are the sort of things developers should be shot for:

Apps that don’t cache downloaded data for later viewing

Except in special cases (e.g. streaming audio/video, realtime or sensitive content), all downloaded data must be cached locally, and able to be viewed again without an internet connection. Apps that don’t store downloaded content are just crippled web browsers.

Offline App Store reviews

It is unacceptable to nag me to rate your app in the App Store when there is no internet connection. Honestly — don’t ask users to do the impossible.

Repeated connection attempts and repeated error diaglogs

It is unacceptable to repeatedly show error dialogs when there is no internet connection. By all means, try to continuously download updates, but do it silently and in the background. I do not need to be told every 30 seconds that it (still) couldn’t connect.

Locking the UI when checking for updates on startup

When launched, It is unacceptable to block the user in the UI from reading previously-cached data while downloading updated content. By all means, check for updates on start up, but while that is happening, the user must be able to read the previous cached copy, unless they explicitly asked for a refresh from-scratch.

Throwing away cached data then failing to update

It is unacceptable to leave the user with a blank screen because you threw away previously-cached data THEN failed to update. Local data caches should not be cleared until new data has been 100% retrieved successfully and loaded.

Lost form data, please retype

t is unacceptable to ‘lose’ form values and force the user to retype a message when a submit error occurs. Form values must be saved somewhere — either automatically requeued for resubmission, or as a draft that can be edited or cancelled by the user.

Ad priorities

It is unacceptable for an ad-supported app to crash, refuse to start or behave weirdly because it couldn’t connect to the ad server. Are you worried about people using your app, or seeing ads?

Occasionally connected apps

It is unacceptable for any app to refuse to start without an internet connection. Users should always be able to change settings, view and edit previously-cached data and enqueue new requests where possible (to be submitted when a connection is available).

Final thoughts

In general, occasionally-connected computing is a good model for iPhone/Android apps that push/pull data from the Internet. It just needs to be implemented correctly. Like web designers assuming no javascript and using progressive-enhancement to add improved behaviour on top of basic functionality, mobile developers should assume no internet connection is available most of the time — jump at the opportunity to sync when possible, but don’t interrupt the user or assume it won’t fail.

So please, if If you’re a mobile developer, think about us poor Londoners before you deploy your next version!

SqlDropDatabase, SqlCreateDatabase MSBuild tasks

SqlDropDatabase, SqlCreateDatabase MSBuild tasks

When working with SQL, I often find I need to quickly spin up/tear down local developer database instances – for example, setting up a clean environment for integration tests on the build server, or blowing away test data.

To help make this easier, here are a couple of MSBuild tasks I wrote that allow you to drop an existing database:

<SqlDropDatabase ConnectionString="Server=.SQLEXPRESS;Database=AdventureWorks;Integrated Security=SSPI;"                 Database="AdventureWorks" />

… and to create a new (empty) one.

<SqlCreateDatabase ConnectionString="Server=.SQLEXPRESS;Database=AdventureWorks;Integrated Security=SSPI;"                   Database="AdventureWorks" />

It’s also sometimes helpful to be able to parse individual individual keys out of a connection string (e.g. the the database name). This can be very tedious with RegexMatch/RegexReplace, so I wrote a separate MSBuild task to do it:

<SqlParseConnectionString ConnectionString="Server=.SQLEXPRESS;Database=AdventureWorks;Integrated Security=SSPI;">    <Output PropertyName="myDb" TaskParameter="InitialCatalog" />    <Output PropertyName="myServer" TaskParameter="DataSource" />    <Output PropertyName="myTimeout" TaskParameter="ConnectTimeout" /></SqlParseConnectionString><Message Text="Parsed the $(myDb) database on server $(myServer) with timeout = $(myTimeout)." />

Fragmented integration tests – aka the questionable value zone

Fragmented integration tests – aka the questionable value zone

In TDD, different styles of tests can be applied to cover different levels in your code base. Two or three years ago, if you asked me what they were, I would probably have listed them as:

  • Highest granularity – unit tests, quick to run, drive low-level class design
  • Fragmented – integration tests, testing higher-level components and external dependencies (e.g. real SQL database, fake message bus)
  • Whole system at once – slow end-to-end tests, testing for story/feature acceptance at the UI or client API level

However, it has become increasingly clear that fragmented integration tests (somewhere in the middle between unit and full-blown end-to-end integration tests) don’t really provide the same value as their brothers.

They suffer all the disadvantages of both unit and end-to-end tests:

  • Like unit tests, they require setting up mocks/test doubles for collaborating modules
  • Like end-to-end tests, they have a high cost of maintaining external components like databases and integrated third party systems (setting them up, populating them with the right test data, reverting changes for next time etc)
  • Like unit tests, they are brittle and not friendly to refactoring
  • Like end-to-end tests, they are slow to run

… and, over the lifetime of the code base, the only real benefit they provide is slightly faster feedback of problems than end-to-end tests. Is it really worth keeping them?

NHibernate session management and WCF, redux

NHibernate session management and WCF, redux

It’s been nearly a year since I published my method for getting one NHibernate session per WCF operation using Castle’s NHibernate Facility and AutoTx AOP Facility — a method I developed for an application which was having serious session management issues (it was using one session per SQL statement). However, today I ripped it all out.

The method itself still works. There’s nothing wrong with it. As long as you’re only doing one session per WCF operation (or one session per ASP.NET MVC request for that matter), it works great. However, problems arise when you mix other session styles.

For example, our application has a series of long-running background threads for processing jobs on a queue (up to an hour each) — as well as synchronous WCF operations — all requiring NHibernate. In this case, the one-size-fits-all approach using AOP and the container simply couldn’t give us the control we needed over each session’s lifetime, so we removed the Facility from our Windsor container, and instead now do:

  • Register the ISessionFactory in the container, singleton scoped.
  • Inject ISessionFactory and call ISessionFactory.OpenSession(), ISession.BeginTransaction() and ITransaction.Commit() at outer boundaries of your application (e.g. WCF service implementations), and background jobs executing outside the context of a WCF operation.
  • Pass ISession down through your application as a parameter into any methods that access the database. Callees must not hold any reference to it, or try to manage its lifestyle (e.g. closing it, opening their own transactions etc).

(Note: all NHibernate calls are wrapped in a transaction and committed. Even if they are only SELECT statements, it’s still a good practice.)

It has more-or-less the same end effect as AutoTx facility and CallContext-scoped SessionManager, but with the added control of being able to explicitly manage session lifetimes in other situations. It’s a few more lines of code, but it’s also a good example of stop trying to hide your ORM, and just embrace the ISession directly. And a reminder that technical solutions are never infallible, no matter how elegant they might seem.

The road to automated database deployment

The road to automated database deployment

Working in an agile team means delivering software early and often — several times a day even. The only way to achieve this without going crazy doing releases all the time is to eliminate all the manual steps in your release process, until you’re leave with a single mouse-click to get your code into to production.

One of the biggest challenges here is how to handle your app’s back-end database. Application files can be deleted and restored in seconds, websites rolled and and replaced a thousand times, but the database is a living, breathing beast, closely guarded by a separate team of DBAs who usually won’t even let you see what state its in, let alone make changes. If you screw up a database script, it could cost hours of downtime restoring from a backup. So how do you automate changes then? Here’s how we did it on a recent project.

Pre-requisite #1: portable script shipping

I’ll never forget the deployment process on my first major commercial project. During development, everyone shared a ‘working copy’ database, directly adding columns and tables via GUI tools. On release day, a designated person would open up SQL Compare, connect to the dev database, connect to the live database, and generate a script copying all the changes from dev to production.

Needless to say, this was a fairly sub-optimal solution. Here’s some of the problems we developers incurred on a regular basis:

  • The diff scripts only work between specific database versions. If UAT was on a faster development cycle than PROD, we couldn’t use the same scripts between them.
  • Only the final diff script was put in source control, so if the development database crashed or was accidentally wiped in between release cycles, we lost all our changes.
  • SQL Compare can reverse-engineer schema changes, but it can’t reverse-engineer data changes/migration between tables. It’s not even a complete solution.

The last one was the real nail in the coffin for us. If you already have to script data changes by hand… why not go the whole hog and do ALTER/CREATE statements too? That way you can just check in each change as a separate sql script into source control — numbered, so you know which order they go in. No more generating scripts, no more losing our work in the dev database. No more SQL Compare.

Pre-requisite #2: database version tracking table

Given a live database and a stack of SQL scripts, how do you know which ones need to be run? You could start reading going through them, statement by statement, until you find a change that doesn’t appear to be applied and start there — or you could simply have each script write a row to the end of a changelog table like this:

ALTER TABLE ...;DROP TABLE ...;-- other DDL changesINSERT INTO CHANGELOG (16, '0016_customer_info.sql', GETDATE(), USER);

That way, it becomes trivial to find out what scripts have run/need to be run against a database. And putting the special INSERT at the end of each change script ensures it doesn’t add a row unless all previous statements executed successfully.

Pre-requisite #3: database version awareness

When is increasing coupling in your application a good thing? When it’s between the database schema version, and the application running over the top. Your physical data model and application’s persistence model (ORM mappings etc) have to move in lockstep, so it’s a good idea to refuse to start if the database version isn’t correct.

You can do this quite easily by checking the highest-run script number in the CHANGELOG table, or introducing a separate VERSION table. Whatever the strategy used, a loud error on startup is much easier to diagnose than messy runtime errors when a column is missing (fail-fast).

Pre-requisite #4: script privileges

To make our lives easier, we introduced a new rule: all change scripts must be able to be run under the same database user/privileges as the application itself. This means we can use the application’s own connection string to run scripts, and eliminates the need for DBAs or sharing the database administrator password.

Running scripts with the application account means we have to grant our services rights to create and modify tables, views, stored procedures etc (i.e. Oracle’s RESOURCE or MS SQL’s db_ddladmin role). Before you freak out about applications running with elevated privileges, please remember one, this is not a shared database — it’s for exclusive use of our application, there is only one user — and two, this application does not run on desktops, so there is no risk of users uncovering credentials and logging in themselves.

This is the same self-upgrading database model WordPress uses, and we justified that if it’s good enough for the 12 million WordPress sites out there on the greater Internet, then it’s good enough for one little Windows Service running in a locked-down server network.

Anyway. If a script does requires system privileges to run, it probably means it has something to do with storage or security — e.g. storage files or table partitioning — that isn’t actually required for the application to run and thus doesn’t need to be part of the official database version history. Those scripts can thus be run independently of the automatic-upgrade process, as required by DBAs.

Pre-requisite #5: clean up existing installations

We have a number of copies of our applications running in the wild, in various states of disrepair. Scripts that were never run, or ran with ‘continue on error’ enabled, and ad hoc customizations by DBAs, and missing entries from the CHANGELOG table all needed to be smoothed over to make a solid platform before any automated process can take over. In this case, we did it by hand (ironically using SQL Compare), but depending on the number of installations out there, and effort required, you may wish to incorporate these clean up steps in your automated scripts.

End goal: self-upgrading application

From this point, it’s relatively easy to implement an automated upgrade process that checks the CHANGELOG table to find out which scripts haven’t been run yet, and run them. That way it works against any previous database version. Our upgrader tool also performs a number of prepatory and clean-up steps, such as creating the CHANGELOG table if required, and cleaning up any vestigal remains of the previous database deployment process.

This process can be designed, and unit tested, and audited to a greater degree than any human process could ever achieve. You can run it hundreds of times over to tweak it, and test it against all sorts of different database configurations with minimal effort. It can and should become part of your continuous integration and automated build and tests.

Failure and backups

Unfortunately, even with all the extra confidence you get from scripting, there is always a risk of something going wrong on release day. One part of the manual process we’re missing is backups, so we’re currently looking into to add an automated backup step before kicking off (probably a lightweight one, using something like a Snapshot in MS SQL or Flashback in Oracle). That way, we can eventually aim to provide automatic rollback capabilities in the event a script fails.

Final words

I’m not saying that the ours is the only way of achieveing automated database deployment, or that this is neccessarily the best way. We’re still working out the kinks, but I’d say it’s looking pretty good so far.

The Fat ViewModel

If someone asked you, what are the building blocks of MVVM, what would you say? Models, Views, and ViewModels, of course. It’s in the name. But really, there are two others:

  • Models
  • Views
  • ViewModels
  • Commands
  • Events

If Commands and Events aren’t strongly represented in your application, I’d say there is a strong chance it isn’t factored very well.

One problem I see quite often is the Fat ViewModel: a long, bloated class that violates SRP by presenting complex application Commands to the view, and implementing them too.

Symptoms

You can tell you have a Fat ViewModel if any of the following are true:

  • Instead of having a separate class for each Command, your ViewModel uses DelegateCommands (aka RelayCommands) to invoke methods on itself.
  • Your ViewModel has three properties, two commands, and is 300 lines long.
  • Your ViewModel has a large number of services injected into it.
  • Your ViewModel tests include assertions for both presentation and application behaviour.
  • Testing simple UI behaviour — e.g. a button should be disabled after it has been clicked — requires excessive mocking of dependencies.
  • Your ViewModel tests frequently call xyzCommand.Execute().
  • Commands cannot easily be re-used by other ViewModels. Your application is not modular.
  • ViewModels update their state directly, instead of listening for global application Events.

Instead, if you extract Commands into separate classes, that publish their results via Events, you will benefit by having:

  • Skinny and light ViewModels.
  • Commands that can be developed and tested in isolation.
  • Commands that encapsulate and mask complex logic.
  • Separation of presentation logic (ViewModels) from application logic (Commands).
  • A catalog of clearly defined and reusable Commands that be composed into new ViewModels.

Whither DelegateCommand?

From the cases I have seen, I have no doubt that DelegateCommands are the primary cause of Fat ViewModels — they encourage developers to implement Commands using local ViewModel methods, which results in poorly-factored code. For this reason, I consider DelegateCommands to be in the same bad code smell category as ServiceLocator: as an anti-pattern, with few legitimate uses. (One is when the Command is entirely self-contained within the ViewModel (i.e. does not collaborate with any other object), the other when genuinely delegating to another object. But in that case, the other object should probably be a Command anyway.)

IIS vs a Windows Service: some important considerations

Can’t decide whether to host your WCF service in IIS or a Windows Service? Consider the additional steps you’ll need to perform, explain, troubleshoot, and write documentation for if you follow the IIS route:

  • Ensure IIS is installed.
  • Run aspnet_regiis -i to install .NET ISAPI module.
  • Run ServiceModelReg –i to install handlers for *.svc file types.
  • Creating, starting a new App Pool running as a domain account.
  • Set your Application to use the new App Pool instead of DefaultAppPool.

Plus, EITHER: (II6/Server 2003)

  • Ensure the .NET 2.0 Web Service Extension is enabled.
  • Add the domain account to local IIS_WPG group.
  • (If required) cscript.exe adsutil.vbs set W3SVC/AppPools/Enable32BitAppOnWin64 “true”

OR: (IIS7/Server 2008)

  • Ensure IIS6 Compatibility components are installed so *.vdproj installers can run.
  • Add the domain account to local IIS_IUSRS group.
  • (If required) set Enable 32-Bit Applications = true

If you are working in an environment like ours with developers in London, servers in Germany, and the ops team in India, where getting server access is harder than getting an appointment with the pope, I’d recommend sticking with Windows Services unless you really need IIS.

How to lose customers through bad UX

I just got a strange validation bug, trying to buy something on eBay UK:

After about eight attempts (trying different browsers, local/international phone number prefixes etc), I emailed them to report it, and find out maybe if I am doing something wrong. Here is their response:

Hello Richard. My name is Elma from PayPal customer service.

I reviewed your account carefully to check why you are unable to use your card and saw that you were trying to pay a £555.00 GBP transaction with your credit card. It appears that this particular payment cannot be funded by a credit card because of our security model.

I would like to assure you that there is nothing wrong with your credit card or your PayPal account. As part of our commitment to protect you and all our customers, we review all transactions that go through us. This payment got declined because we detected that it might not be safe for you to use your credit card for this transaction. Don’t worry. I assure you that it’s just for this particular transaction. You can still use your credit card for your future transactions.

This is amazing. PayPal are reporting a permanent, this-form-will-never-work-so-don’t-bother-filling-it-out problem to users as an input validation error. And how do users react to validation errors? They double check their details and type them in again. And again. And again, until they’ve gone slightly mad, spending hours scrutinizing every pixel in every digit in their credit card and telephone number for mistakes.

In the end, it wasn’t until I contacted PayPal directly (hint: their feedback form is not exactly easy to find) that I was told my credit card would never work for this particular purchase, and the whole thing was a waste of time. (I wonder how many customers they lost who didn’t bother to fill out a bug report?)

If you are writing software like this, you have BIG problems.

Reactive Extensions and Prism: LINQ to your Event Aggregator

A lot of people have been talking about the Reactive Extensions for .NET, a flash new library from Devlabs which lets you do LINQ to .NET events just like you can with collections. My team at work has started using it pretty heavily, and today I wrote an adapter that allows you to use Rx over events published on the event aggregator in a Prism/Composite WPF application.

Here’s an example of using it in an imaginary chat client, to filter incoming messages from a particular person:

public class ConversationViewModel : IDisposable{    public IContact Friend { get; private set; }    public ObservableCollection<IMessage> Messages { get; private set; }    public ConversationViewModel(IContact friend,         IEventAggregator eventAggregator)    {        // Interested only in messages sent by the person we are talking to.        var messageReceivedEvents = eventAggregator            .GetEvent<MessageReceived>()            .AsObservable()            .Where(msg => msg.Sender.Equals(Friend));        eventSubscription = messageReceivedEvents.Connect();        messageReceivedEvents.Subscribe(msg => Messages.Add(msg));    }        // We will keep receiving messages until the subscription is disposed.    IDisposable eventSubscription;}

It was a good exercise that helped me understand a bit more about how Rx works, and illustrates how easy it is to integrate with callback-based event systems (e.g. your favourite message bus).

You can grab the code here: CompositePresentationEventExtensions.cs

Update Jun 16 2010: Added finalizer to CompositePresentationEventSubscription.

Update Feb 9 2012: Fixed bug found by Ariel Ben Horesh where keepSubscriberReferenceAlive needed to be true.