微软Orleans连接MongoDB

微软的Orleans在其Sample Projects中给出了一个连接MongoDB作为其存储提供程序(Storage Provider)的案例。


为了连接Mongo,你需要用NuGet下载“Official MongoDB C# Driver”驱动。这个插件是由10Gen, Inc提供的。

首先你需要下载和安装MongoDB的windows版本。下载地址为:

https://www.mongodb.org/dr/fastdl.mongodb.org/win32/mongodb-win32-x86_64-3.2.4-signed.msi/download

通过在存储服务中保存数据,自定义的存储提供程序使你能够扩展Orleans的能力。本例中,我们将数据保存在文件系统和MongoDB中。

虽然二进制的数据在数据持久化方面通常性能更好,本例仍旧使用了JSON格式,因为其具有更好的可读性和易于校验,这对于代码范例来说很重要。在实际应用中,可能你会自行决定是否要采用其它的序列化方式。


运行范例

范例工程包括4个项目:存储提供程序库,3个测试库,解决方案结构与HelloWorld范例相同。

微软Orleans连接MongoDB_第1张图片

注意:Orleans范例代码中都是NewtonSoft.Json version 7.0.0的,实际运行调试的之前你需要用Nuget更新一下最新的插件。我的是8.0.2版本。

微软Orleans连接MongoDB_第2张图片


先把DevTestServerConfiguration.xml文件中的存储提供程序相关的注释去掉:

 
           


编译,调试运行Test.Client项目(请注意输入的文本结果):

Successfully started Orleans silo 'host-001' as a Primary node.

We just wrote something to the persistent store. Please verify!

Orleans Silo is running.
Press Enter to terminate...


停止调试,定位到Test.Client项目的bin\Debug文件夹下,会发现多出来一个Samples.FileStorage文件夹:
微软Orleans连接MongoDB_第3张图片


开启命令行窗口,定位到Test.Client\bin\Debug\Samples.FileStorage目录下,用more命令查看文件的详细信息,能够看到其中的JSON内容:

微软Orleans连接MongoDB_第4张图片


然后我们再次重新启动客户端程序。现在由于Orleans的状态保持机制,输出的内容与上一次调试运行的结果就不一样了:

This was found in the persistent store: John, Doe, Male


Orleans Silo is running.
Press Enter to terminate...


如果你是安装了MongoDB来作为存储提供程序,你可以重复上一个过程以测试数据库来实现状态保持机制。注意改写一下DevTestServerConfiguration.xml中的配置信息,并确保Mongod.exe进程在运行中。如果用Mongo.exe检查数据,你可以看到:

MongoDB shell version: 2.4.6
connecting to: test
> use orleanssamples
switched to db orleanssamples
> db.PersonState.find()
{ "_id" : ObjectId("533391afcf20b011307a82bf"), "FirstName" : "John", "LastName" : "Doe", "Gender" : 0, "key" : "0000000000000000000000000000000003ffffffc0950639" }
>

(译者注:以下是实际运行一个远程MongoDB的结果截屏)

微软Orleans连接MongoDB_第5张图片



设计

BaseJSONStorageProvider包含了JSON的序列化和反序列化代码,实现了IStorageProvider接口的几个主要接口方法,Init(),ReadStateAsync(),WriteStateAsync()和ClearStateAsync()。

与数据层进行交换的逻辑委托给了DataManager类层次结构,包括IJSONStateDataManager,GrainFileStateManager, 和GrainStateMongoDataManager.这些类的Delete,Read和Write方法直接对应了存储提供程序类的相应方法。

本例中没有涉及通过.NET与文件系统或者MongoDB进行交互的细节,这将中其它地方讨论。不过,仍旧需要解释几点。

中两个例子中,grain类型的名字被用于实例集合的命名;在文件存储的例子中,集合名称与存储数据的文件夹名称相对应,而其主键则指明了特定的实例。在MongoDB的例子中,grain类型名代表了一个数据库集合,而主键则用于特定的文件名。

在MongoDB的例子中,在带有键值的写操作时JSON的结构被增强了,增加了一个元素,key,其中包含了grain的键值并使我们可以在读操作时查询相应的文件。此外,Mongo内带用于文档识别的_id参数也被仔细处理。

public Task Write(string collectionName, string key, string entityData)
{
    var collection = GetOrCreateCollection(collectionName);

    var query = Query.EQ("key", key);
    var existing = collection.FindOne(query);

    var doc = MongoDB.Bson.Serialization.BsonSerializer.Deserialize(entityData);
    doc["key"] = key;

    if ( existing == null )
    {
        collection.Insert(doc);
    }
    else
    {
        doc["_id"] = existing["_id"];
        collection.Update(query, Update.Replace(doc));
    }
    return TaskDone.Done;
}


在进行读操作时,_id字段从发回给调用方的JSON文档中去除,因为此字段不包含在Orleans的数据模型中。

public Task Read(string collectionName, string key)
{
    var collection = GetCollection(collectionName);
    if (collection == null)
        return Task.FromResult(null);

    var query = Query.EQ("key", key);
    var existing = collection.FindOne(query);

    if (existing == null)
        return Task.FromResult(null);

    existing.Remove("_id");
    existing.Remove("key");

    var strwrtr = new System.IO.StringWriter();
    var writer = new MongoDB.Bson.IO.JsonWriter(strwrtr, new MongoDB.Bson.IO.JsonWriterSettings());
    MongoDB.Bson.Serialization.BsonSerializer.Serialize(writer, existing);
    return Task.FromResult(strwrtr.ToString());
}



原文链接:

http://dotnet.github.io/orleans/Samples-Overview/Storage-Providers


你可能感兴趣的:(Orleans,MongoDB,.NET)