Getting to grips with RX

Reactive Extensions 

Rx for short - is a pretty neat little framework by Erik Meijer. I've sort of been avoiding it - don't really know why, but Copenhagen .Net User Group (CNUG) recently had Tamir Dresher do an introduction to the tech (and blatantly plug his upcoming book on the subject), and it was a bit of an eye opener, so I've decided to dedicate some time to get to the bottom of this - and blog about it.

The Limitations of IEnumerable

We all know IEnumerable and it's trusty sidekicks, foreach(var foo in bar) and .Select/.Where/.Any/.All/.etc. It's wonderfully convenient to have an interface, where going through a collection/set/array/list is a matter of letting the compiler do its magic.

foreach(var foo in bar)
    // do stuff with foo

But what if bar contains something exotic like a bunch of Task<T>'s that are currently crunching away on healthy portions of data. We can't really be sure when any one of them will return, but we can be 100% sure, that they won't return in the same order we enumerate them, so we will be wasting time - even if we employ Parallel.ForEach.

Ideally we would like to be able to respond to the tasks completing as events, such that when the first Task completes, we immediately respond to it. We would also like to know when the last Task completes, in order to be able to shutdown gracefully.

Another scenario: What if bar is in fact not a collection with a fixed number of elements. Think a mailbox or maybe a performance counter. New elements keep popping into it, which makes foreach-ing over the collection soft of impossible. We're forced to employ a different strategy probably involving queues and maybe OnNew-events which we need to subscribe to - and which threads are now accessing which parts of the application.

IObservable to the Rescue

Rx is an implementation of the Reactor-pattern  (hence Reactive) in Linq (which are eXtensions). IObservable is mathematically dual to IEnumerable, which could be translated into something like 'The same but seen from the other side'. In stead of pulling foos out of bar, let bar push foos out to you.

In the case of an IObservable of Task<T>, the result would be to get the Tasks in the order they complete. In the case of the mailbox or performance counter, the IObservable implementation would simply respond to additions by emitting them to anyone listening without further notice.

bar.Subscribe(bar => // doStuff with bar)

Oh, and don't get me wrong, it's not really that simple - but the gist of it is this: Rx provides a pattern for solving concurrency-issues in a short and elegant way.

I'll be examining Rx in detail in the next couple of weeks

A few links





The NUnit upgrade

Recently we decided that an upgrade was long overdue - our unittest project was using NUnit 2.6.4, and v3.4.1 had been around for at couple of weeks.

So, we did what anyone would, and let NuGet do the heavy lifting. Of course there were a few breaking changes, but nothing we couldn't handle. 30 minutes and 8 commits later, we were officially back to 2016. But TeamCity didn't agree. It seemed that after an NUnit run, the nunit-agent.exe process was never killed off, keeping pesky references to the assets in the bin-folder thus preventing the next build from succeeding.

So, a bit of digging and we found this: TL;DR: the above happens if nunit-console output is redirected to anything but std-out, like TeamCity. Fix - probably NUnit 3.5, but they're taking it seriously

Screengrap from github/nunit/issue/43

Oh, well. Back to 2.6.4 and now I've written this, to remind me why our unittest project was left behind in 2015

Update 27.nov.2016
NUnit released v3.5 recently, and we've tried it out - still doesn't work for us. We get intermittent "AppDomainUnloadExceptions" presumably because something in our test fixtures is being kept alive for longer than the timeout.