Search code examples
.netmonocouchdbmembase

Membase CouchDB can't get it working with Mono on Mac OS X


I've successfully installed Membase Server, their "Sub-millisecond access latency" feature is actually forced me to write this question, otherwise I would ten times already switched to MongoDB. So the question: I have properly installed and configured my Membase Server now I want my .NET client application to get access to this database, for this purpose I'm using their Enyim .NET Client. I have written the following test application:

using System;
using System.Linq;
using System.Diagnostics;

using Membase;
using Membase.Configuration;

namespace CouchDB
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var config = new MembaseClientConfiguration()
            {
                Bucket = "helloworld",
                BucketPassword = "123",
                NodeLocator = typeof(Enyim.Caching.Memcached.DefaultNodeLocator),
                Transcoder = new Enyim.Caching.Memcached.DefaultTranscoder(),
                KeyTransformer = new Enyim.Caching.Memcached.TigerHashKeyTransformer(),
                PerformanceMonitorFactory = null // I'm on Mac OS X
            };

            config.SocketPool.MinPoolSize = 10;
            config.SocketPool.MaxPoolSize = 20;
            config.SocketPool.DeadTimeout = TimeSpan.FromSeconds(10);
            config.SocketPool.ConnectionTimeout = TimeSpan.FromSeconds(5);
            config.Urls.Add(new Uri("http://localhost:8091/pools/default"));

            var client = new MembaseClient(config);


            var spoon = client.Get<String>("Spoon");

            Console.WriteLine(spoon);
        }
    }
}

The problem occurs when I'm trying to create a client, exception occurs which doesn't even show complete stack, tells only

"Cannot cast from source type to destination type"

at System.Web.Script.Serialization.JavaScriptSerializer..ctor(resolver=null, registerConverters=false)


Solution

  • I've spent some hours on this problem. There is a bug in the Mono runtime (it's still present in 2.10.5 AFAIK), that causes a conflict between two versions of System.Web.Extensions : 3.5 and 4.0

    The DLL provided for Membase client (and now Couchbase client) are linked with the 3.5 version. I don't know what references the 4.0 version, but still, something does. So the solution is either to apply a redirection (I haven't tested it) :

    <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name="System.Web.Extensions"
                              publicKeyToken="31bf3856ad364e35"
                              culture="neutral" />
            <bindingRedirect oldVersion="3.5.0.0"
                             newVersion="4.0.0.0"/>
         </dependentAssembly>
      </assemblyBinding>
    </runtime>
    

    Or recompile the client (that's what I've done). There are two minor problems when compiling the client under mono : in MemcachedNode.cs, there is an explicit implementation of the Failed event. Since it is unnecessary (there is no other conflicting Failed event implemented), you can just remove the lines. Also there is a SetTcpKeepAlive that you can remove (I think it's safe).