将对象引用存储为颗粒状态

时间:2016-01-17 14:01:28

标签: c# serialization orleans

我有一个包含IContainerGrain个对象列表的格NodeNode类型的对象需要能够通过这种方式相互通信:

class Node {

    public IContainerGrain Container { get; set; } // This is an object reference (!) to the container grain

    private void TriggerExecution() {
        var receiverId = 123;
        Container.GetNode(receiverId).SendSomeMessage(); // Communicate through container grain
    }
}

现在我想要保留包含节点列表的IContainerGrain状态。粒度的序列化触发了所有包含Nodes的序列化,然后触发IContainerGrain的序列化。这是不受支持的,我得到一个例外。

我的方法

我的非工作方法是将Node.Container标记为NonSerializable并在Grain中实现以下内容:

public override Task OnActivateAsync()
{
    if (State.ContainedNodes == null)
    {
        State.ContainedNodes = new List<INode>();
    }
    foreach (var n in State.ContainedNodes)
    {
        n.Container = this; // On activation initialize container
    }
    return base.OnActivateAsync();
}

但是,这总是不起作用,我继续在Node.TriggerExecution()中获取NullReferenceExceptions,因为Container属性为null。

问题

  1. 能够将对象引用存储在此纹理中的对象中的最佳方法是什么?我可以轻松地使用谷物参考,但这会使Container.GetNode(...)操作变慢。我知道如果我使用谷物到Node的1:1映射就不存在这个问题,但这对我的应用来说有太多的开销。

  2. Orleans序列化是否存储引用或是否始终执行深层复制?序列化和反序列化后引用保持不变将是很好的。

2 个答案:

答案 0 :(得分:0)

  1. 能够通过在IContainerGrain中创建另一个容器对象来解决此问题。 弄清楚调用了序列化程序,因为从另一个谷物实例调用了GetNode()

  2. 我认为答案是参考文献保持不变,但我仍然很乐意确认这一点:)

答案 1 :(得分:0)

容器中有多少谷物? 谁在执行TriggerExecution?为什么客户不能立即调用节点粒度?

如果客户端调用节点粒度,那么您将受益于拥有多个用于分散请求的网关。

创建颗粒引用也不昂贵-从您的示例中,如果容器中不存在引用,我不会担心创建新的节点颗粒引用。

最佳