0

我有一个IContainerGrain包含Node对象列表的谷物。类型的对象Node需要能够通过这个grain相互通信:

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();
}

但是,这并不总是有效,我不断获得 NullReferenceExceptions Node.TriggerExecution(),因为 Container 属性为空。

问题

  1. 能够从这个grain中的一个对象存储一个对grain的对象引用的最佳方法是什么?我可以很容易地使用谷物参考,但这会使Container.GetNode(...)操作变慢。我知道如果我使用 1:1 的 grain 映射到Node,则不会存在此问题,但这对我的应用程序来说开销太大。

  2. Orleans 序列化是这样存储引用还是总是执行深拷贝?在序列化和反序列化之后保留完整的引用会很棒。

4

2 回答 2

0
  1. 能够通过在IContainerGrain. 发现调用了序列化程序,因为GetNode()是从另一个grain实例调用的。

  2. 我认为答案是参考文献保持不变,但我仍然很高兴得到证实:)

于 2016-01-17T16:53:54.067 回答
0

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

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

同样创建颗粒参考并不昂贵 - 从您的示例中,如果容器中不存在参考,我不会担心创建新的节点颗粒参考。

最好的

于 2018-08-14T20:52:52.997 回答