我有一个包含IContainerGrain
个对象列表的格Node
。 Node
类型的对象需要能够通过这种方式相互通信:
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。
能够将对象引用存储在此纹理中的对象中的最佳方法是什么?我可以轻松地使用谷物参考,但这会使Container.GetNode(...)
操作变慢。我知道如果我使用谷物到Node
的1:1映射就不存在这个问题,但这对我的应用来说有太多的开销。
Orleans序列化是否存储引用或是否始终执行深层复制?序列化和反序列化后引用保持不变将是很好的。
答案 0 :(得分:0)
能够通过在IContainerGrain
中创建另一个容器对象来解决此问题。
弄清楚调用了序列化程序,因为从另一个谷物实例调用了GetNode()
。
我认为答案是参考文献保持不变,但我仍然很乐意确认这一点:)
答案 1 :(得分:0)
容器中有多少谷物? 谁在执行TriggerExecution?为什么客户不能立即调用节点粒度?
如果客户端调用节点粒度,那么您将受益于拥有多个用于分散请求的网关。
创建颗粒引用也不昂贵-从您的示例中,如果容器中不存在引用,我不会担心创建新的节点颗粒引用。
最佳