Service Fabric:将枚举类移至其他项目

如何解决Service Fabric:将枚举类移至其他项目

最近,为了解决循环依赖问题,我们需要将枚举类移到其他名称空间下的其他项目中。有一些参与者和有状态的服务将这个枚举值的实例保持在可靠状态。

枚举类是这样的:

namespace com.libA
{
    public enum Foo
    {
        None = 0,Foo1 = 1,Foo2 = 2,}
}

我们希望将其移动到名称空间为com.libB的另一个项目中。这些枚举值存储在参与者和有状态服务内部的可靠状态中,并按以下方式获取

Foo foo = await this.StateManager.GetStateAsync<Foo>("FooKey").ConfigureAwait(false);

存储Foo值的actor服务之一是寿命很长的actor。从理论上讲,它可以在快乐的路径中生存到无穷远,并且如果从不从外部调用delete,则它永不停止。我们尝试了简单的重构>移动,并在非产品环境中进行了尝试。这开始在我们的非产品环境中引起SerializationException错误消息显示Expecting element 'Foo' from namespace 'http://schemas.datacontract.org/2004/07/com.libB'.. Encountered 'Element' with name 'Foo',namespace 'http://schemas.datacontract.org/2004/07/com.libA'.

这些异常即将出现在较早的参与者中获取Foo的值之前。

我的问题是:

  1. 如何将Foo移至命名空间com.libB?两阶段升级对您有帮助吗?
  2. 是否有可能做到这一点而又不会造成数据丢失/损坏?

解决方法

您可以将DataContract属性和名称空间添加到您的类型中。 由于您已经在生产环境中运行,因此可以使用错误中的名称空间来解决问题。

示例:

[DataContract(Name = "Foo",Namespace = "http://schemas.datacontract.org/2004/07/com.libA")]
public enum Foo
{
   // ...
}

更好的方法可能是制定升级计划。

  1. 让这两种类型共存
  2. 检索状态时,请尝试使用机制,并使用旧类型进行检索,如果由于序列化异常而失败,请尝试使用新类型。
  3. 在保留状态时,将状态转换为旧类型时,将其转换为新名称空间中的新类型。 (添加一些日志记录,以便您可以验证转换是否发生)
  4. 部署进行测试,看看是否可行,是否可以部署到生产环境
  5. 删除旧类型,删除转换代码
  6. 如果可以正常部署到生产环境,请进行测试以进行测试。
,

一种选择是为使用DataContractSerializer的所有类型创建custom serializer wrapping Foo,在反序列化期间修复/忽略名称空间。

IReliableStateManager.TryAddStateSerializer用于注册一个 给定类型T的自定义序列化程序。此注册应 发生在StatefulServiceBase的构建中,以确保 在恢复开始之前,所有可靠集合都可以访问 相关的序列化程序以读取其持久数据。

  • IStateSerializer<OrderKey>.Read(BinaryReader reader)中,以XML格式读取序列化的数据
  • 在需要的地方更改XML名称空间
  • 将XML馈送到DataContractSerializer以创建对象
  • 返回对象

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?