Tuesday, June 21, 2011

The definitive list of Rx sites

Over at the Rx forums, Eamon_OTuathail has created what seems to be the list of Rx sites. It is a list of Blogs and open source projects.
Great stuff. This should save a lot of time for a lot of people.
http://social.msdn.microsoft.com/Forums/en-US/rx/thread/2cbd3b1c-d535-46ba-a9cf-3cd576a8e7c2
Humbled to make the grade.

EDIT: Hopefully www.IntroToRx.com will also make the grade. It is the online book that evolved from the blog series.

Saturday, June 18, 2011

Isolating custom Library dependencies versions from consumer dependency versions

This post is more about the CLR and dependency management than it is about Rx. However at this point in Rx’s lifecycle it seems relevant to comment on. The same principles could obviously be applied to open source projects et. al.

I have recently heard of an interesting situation that no-doubt has proved troublesome to people before. This problem is particularly interesting with Rx and it’s recent rate of versions. If you are trying to incorporate Rx into a library of yours and you then want to publish that library, you are effectively forcing users to use the same version of Rx that you do. Considering that a version of Rx comes out say every two months and that often there are breaking changes, this can create quite a mess. It is also made more interesting that up until recently they have not specified if a release was experimental or considered stable.

To provide an example to better understand my particular point; imagine you have a library that wraps a messaging platform. You want to avoid the use of Events and APM, and expose things via IObservable<T>. You feel happy that IObservable<T> is exposed natively in .NET 4 so you should not have to expose your implementations of Rx. You do however, want to use Rx as it has features you need and don’t want to (re-)write yourself. Your standard approaches to package/deployment are:

  • deploy the parts of the Rx libraries you use with your code. Users can just put them all into a “lib\MyFramework” folder and reference them.
  • excluded the libraries from your code and set Specific Version = False and hope your code will work with the consumer’s version of Rx
  • use a package management tool like Nuget to publish your package and specify the valid versions of Rx your library will work with.
  • rely on things being in the GAC so you can utilise the side-by-side versioning it provides
  • just try and implement the parts of Rx you want and avoid DLL Hell.

I gave this some thought and I think I have come up with a solution that could help library authors protect themselves. While there is the obvious option of using Nuget as part of your dependency management, this does not solve the problem, it just eases the pain. If the customer wants to use the latest version of Rx and you only support the 3 previous versions, your customer is still in some trouble.

The theory i had was that I can specify the specific version of Rx I want to reference in my library, the problem being that it may be named the same as the client’s referenced version. Depending on where their references were built to, they could overwrite each other. It seemed the solution was to embed the dependency into my library.

This turns out to actually be quite easy. If you have a project in visual studio that references your version of Rx, you have to follow these steps:

  1. Ensure you have a file reference (not a project or a GAC reference) to the dependency, in this case System.Reactive.dll
  2. Set the reference to be Specific Version = True
  3. Set the reference Copy Local = False
  4. Embed the dependency into your library. I created a folder in my project called EmbeddedAssemblies. I “Add Existing…” to this folder, navigate to the dependencies (just System.Reactive.dll in this case), and then choose “Add as Link…
  5. Set the “Build Action” of  the newly added link to Embedded Resource
  6. Ensure that the resource is loaded correctly at run time…

The last part of that list proves to be not too hard. You can hook on to the AppDomain.AssemblyResolve event and load your embedded resource. You can return your embedded dependency by reading the byte stream and creating the assembly from it and then returning that in the event handler

internal static class DependencyResolver
{
  private static int _isSet = 0;

  internal static void Ensure()
  {
    if (Interlocked.CompareExchange(ref _isSet, 1, 0) == 0)
    {
      var thisAssembly = Assembly.GetExecutingAssembly();
      var assemblyName = new AssemblyName(thisAssembly.FullName).Name;
      var embededAssemblyPrefix = assemblyName + ".EmbeddedAssemblies.";

      var myEmbeddedAssemblies =
        Assembly.GetExecutingAssembly().GetManifestResourceNames()
          .Where(name => name.StartsWith(embededAssemblyPrefix))
          .Select(resourceName =>
                    {
                      using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
                      {
                        var assemblyData = new Byte[stream.Length];
                        stream.Read(assemblyData, 0, assemblyData.Length);
                        return Assembly.Load(assemblyData);
                      }
                    })
          .ToDictionary(ass => ass.FullName);

      AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
                                                    {
                                                      Assembly assemblyToLoad = null;
                                                      myEmbeddedAssemblies.TryGetValue(args.Name, out assemblyToLoad);
                                                      return assemblyToLoad;
                                                    };
    }
  }
}

You can return null in the event handler to say I don't know how to load this assembly. This allows others to be able to have a go at loading the assembly in the same way.

Next, to ensure that my embedded dependency resolver is called, I opted to make a call to it in the static constructor of the key types in my library. eg

public class SomeProvider
{
  static SomeProvider()
  {
    DependencyResolver.Ensure();
  }

  //other stuff goes here...
}

Have a look at the example code by downloading this zip file

Caveats : This is a thought and the code and concepts are only demo quality. I have not used this in production quality code. I also have not verified that the license allows for this style of packaging.

Further links:

Sunday, June 5, 2011

Rx v.1.0.10425–Breaking changes!

For those that follow Rx, many will have noticed a new drop was made available in late April 2011. This was interesting for numerous reasons:

  1. I believe that it was the first drop since the Rx team move off of the dev labs site and on to the Microsoft Data site
  2. They have supplied two downloads, Supported and Experimental
  3. It is available via Nuget
  4. It broke most of the sample code of this blog
  5. ...It has massive breaking changes !

The first thing I noticed was that only the more recent frameworks were in the “supported” release i.e. .NET 4, Silverlight 4 and Windows Phone. Next, when you open up the install directory (which has moved, again) the files are different to previous releases.

This is a comparison of the location and files of the old v.s. new version (.NET 4 target):

C:\Program Files\Microsoft Cloud Programmability\Reactive Extensions\v1.0.2856.0\Net4
System.CoreEx.dll
System.Interactive.dll
System.Linq.Async.dll
System.Reactive.ClientProfile.dll
System.Reactive.dll
System.Reactive.ExtendedProfile.dll
System.Reactive.Testing.dll

C:\Program Files\Microsoft Reactive Extensions SDK\v1.0.10425\Binaries\.NETFramework\v4.0
Microsoft.Reactive.Testing.dll
System.Reactive.dll
System.Reactive.Providers.dll
System.Reactive.Windows.Forms.dll
System.Reactive.Windows.Threading.dll

Note the files names are named System.Reactive instead of hijacking the existing BCL namespaces such as System, System.IO, System.Linq etc. Here are a list of the old and new Namespaces found in the Rx libraries with the count of the Types in each namespace.

C:\Program Files\Microsoft Cloud Programmability\Reactive Extensions\v1.0.2856.0\Net4
System                         6
System.Collections.Generic     21
System.Concurrency             14
System.Diagnostics             1
System.Disposables             8
System.IO                      1
System.Joins                   34
System.Linq                    13
System.Reactive.Testing        4
System.Reactive.Testing.Mocks  10
System.Threading.Tasks         1
System.Web                     1
System.Windows.Forms           1
System.Windows.Threading       1

C:\Program Files\Microsoft Reactive Extensions SDK\v1.0.10425\Binaries\.NETFramework\v4.0
Microsoft.Reactive.Testing     7
System                         1
System.Reactive                10
System.Reactive.Concurrency    16
System.Reactive.Disposables    9
System.Reactive.Joins          34
System.Reactive.Linq           8
System.Reactive.Subjects       8
System.Reactive.Threading.Tasks 1

Summary of impact

Here is a quick list of the changes that have affected the code from the samples off this blog

Unit has been moved to System.Reactive. I imagine to prevent any conflicts with FSharp’s Unit?

EventLoopScheduler no longer has a constructor that takes a string for the name of the thread, it instead takes a function to act as a Thread Factory so you can use that to specify a name for the thread instead.

Similar methods have been collapsed to overloads. For example; BufferWithTime, BufferWithCount & BufferTimeOrCount are all just Buffer with various overloads. Same goes for WindowWithTime, WIndowWithCount & WindowTimeOrCount. GenerateWithTime is now just an overload of Generate. CreateWithDisposable is now just an overload of Create.

Potentially confusing names have been adjusted. I must admit, I found AsyncSubject and odd name, and also found it odd that Prune was the method you would use to transform an existing observable to one that exhibited AsynchSubject behaviour. The new version of this is the far more appropriately named TakeLast(int). Obviously just pass a value of 1 to get the old semantics of Prune.

The Run method has now been renamed the more obvious (well to new comers) ForEach. It is a bit of an enumerable construct, but that is cool.

My big problem has been the disappearance of the IsEmpty extension method. So I had a long think about this and have decided that you can replace it by creating your own extension method that looks like this

public static class ObservableExtensions
{
  //Is missing now the System.Interactive has been dropped
  public static IObservable<bool> IsEmpty<T>(this IObservable<T> source)
  {
    return source.Materialize()
        .Take(1)
        .Select(n => n.Kind == NotificationKind.OnCompleted
                      || n.Kind == NotificationKind.OnError);
  }
}

For even more details, check out the forum post that has the summary release notes and allsorts of rants about what has changed and what is causing problems for other (+ some helpful tips).

http://social.msdn.microsoft.com/Forums/en-US/rx/thread/527002a3-18af-4eda-8e35-760ca0006b98

This change is not one that you can just take and expect all to be well. However assuming that you can just update some references and add the missing extensions to you own library, you could be fine.

Changes to TestScheduler

The real problems come from the big changes to the testing part of Rx. This appears to have undergone a complete change and most of my existing code does not work. This looks like a big and possibly welcome change to the TestScheduler.

Problems with the previous TestScheduler

There were some fundamental problems with the TestScheduler as it was. There were problems with running it to a specific point in time if there were not any actions scheduled for that point in time. For example, the old TestScheduler would allow you to request that it run to say 5seconds. If there were no actions scheduled, then the clock would not actually advance. You could then Schedule an action to happen at 3Seconds (effectively in the past) and then call Run and it would execute the actions. Hmmm.

TestScheduler scheduler = new TestScheduler();
scheduler.Schedule(()=>{Console.WriteLine("Running at 1seconds");}, TimeSpan.FromSeconds(1));
scheduler.RunTo( scheduler.FromTimeSpan(TimeSpan.FromSeconds(5)));
//The next line is scheduled in the past and somehow this all works!
scheduler.Schedule(()=>{Console.WriteLine("Running at 3seconds");}, TimeSpan.FromSeconds(3));
scheduler.Run();

There also seemed to be a lack of functionality for running to a relative point in time. I have used these extension methods to work around this shortcoming.

public static class TestSchedulerExtensions
{
  /// <summary>
  /// Runs the scheduler from now to the given TimeSpan. Advances relative to it's <c>Now</c> value.
  /// </summary>
  public static void RunNext(this TestScheduler scheduler, TimeSpan interval)
  {
    var tickInterval = scheduler.FromTimeSpan(interval);
    scheduler.RunTo(scheduler.Ticks + tickInterval + 1);
  }

  public static void RunTo(this TestScheduler scheduler, TimeSpan interval)
  {
    var tickInterval = scheduler.FromTimeSpan(interval);
    scheduler.RunTo(tickInterval);
  }

  public static void Step(this TestScheduler scheduler)
  {
    scheduler.RunTo(scheduler.Ticks + 1);
  }

  /// <summary>
  /// Provides a fluent interface so that you can write<c>7.Seconds()</c> instead of <c>TimeSpan.FromSeconds(7)</c>.
  /// </summary>
  /// <param name="seconds">A number of seconds</param>
  /// <returns>Returns a System.TimeSpan to represents the specified number of seconds.</returns>
  public static TimeSpan Seconds(this int seconds)
  {
    return TimeSpan.FromSeconds(seconds);
  }
}

However on initial inspection of the new TestScheduler there appears to be features that support running to an absolute or relative time. It looks like that the Post on testing Rx will need a re-write Sad smile

Technorati Tags: ,