Azure service fabric 服务结构:将枚举类移动到其他项目

Azure service fabric 服务结构:将枚举类移动到其他项目,azure-service-fabric,service-fabric-stateful,service-fabric-actor,Azure Service Fabric,Service Fabric Stateful,Service Fabric Actor,最近,为了解决循环依赖关系,我们需要将枚举类移动到不同命名空间下的不同项目中。有一些actor和stateful服务将此enum值的实例保持在其可靠状态 枚举类是这样的: Foo foo = await this.StateManager.GetStateAsync<Foo>("FooKey").ConfigureAwait(false); namespace com.libA { 公众谘询委员会 { 无=0, Foo1=1, Foo2=2, } } 我们希望

最近,为了解决循环依赖关系,我们需要将枚举类移动到不同命名空间下的不同项目中。有一些actor和stateful服务将此enum值的实例保持在其可靠状态

枚举类是这样的:

Foo foo = await this.StateManager.GetStateAsync<Foo>("FooKey").ConfigureAwait(false);
namespace com.libA
{
公众谘询委员会
{
无=0,
Foo1=1,
Foo2=2,
}
}
我们希望将其移动到另一个名称空间为
com.libB
的项目。这些枚举值以可靠状态存储在actor和stateful服务中,并按如下方式获取:

Foo foo = await this.StateManager.GetStateAsync<Foo>("FooKey").ConfigureAwait(false);
Foo-Foo=wait this.StateManager.getstateAync(“FooKey”).configurewait(false);
存储
Foo
值的actor服务之一是一个非常长寿的actor。从理论上讲,它可以在快乐的道路上一直生存到无穷远,而且如果从不从外部调用delete。我们尝试了simple refactor>Move,并在非prod环境中进行了尝试。这在我们的非产品环境中开始导致
SerializationException
。错误消息显示:
应为命名空间中的元素“Foo”http://schemas.datacontract.org/2004/07/com.libB'.. 遇到名称为“Foo”的“元素”,命名空间为http://schemas.datacontract.org/2004/07/com.libA“。

这些异常是在获取较旧参与者中的
Foo
值之前出现的

我的问题是:

  • 我们如何将
    Foo
    移动到命名空间
    com.libB
    ?两阶段升级在这里有用吗
  • 甚至可以在不丢失/损坏数据的情况下这样做吗

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

    例如:

    [DataContract(Name = "Foo", Namespace = "http://schemas.datacontract.org/2004/07/com.libA")]
    public enum Foo
    {
       // ...
    }
    
    更好的方法可能是制定升级计划

  • 让这两种类型共存
  • 检索状态时,使用try机制,使用旧类型检索,如果由于序列化异常而失败,请使用新类型尝试
  • 在持久化状态时,将其转换为新命名空间中的新类型(当它是旧类型时)。(添加一些日志记录,以便验证转换是否发生)
  • 部署到测试,查看它是否工作,如果正常,部署到生产
  • 删除旧类型,删除转换代码
  • 部署到测试,查看它是否工作,如果可以,部署到生产环境

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

    例如:

    [DataContract(Name = "Foo", Namespace = "http://schemas.datacontract.org/2004/07/com.libA")]
    public enum Foo
    {
       // ...
    }
    
    更好的方法可能是制定升级计划

  • 让这两种类型共存
  • 检索状态时,使用try机制,使用旧类型检索,如果由于序列化异常而失败,请使用新类型尝试
  • 在持久化状态时,将其转换为新命名空间中的新类型(当它是旧类型时)。(添加一些日志记录,以便验证转换是否发生)
  • 部署到测试,查看它是否工作,如果正常,部署到生产
  • 删除旧类型,删除转换代码
  • 部署到测试,查看它是否工作,如果可以,部署到生产环境
  • 一个选项是为使用
    Foo
    的所有类型创建
    DataContractSerializer
    ,在反序列化过程中修复/忽略命名空间

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

    • IStateSerializer.Read(BinaryReader)
      中,将序列化数据读取为XML
    • 根据需要更改XML名称空间
    • 将XML馈送到
      DataContractSerializer
      以创建对象
    • 返回对象
    一个选项是为使用
    Foo
    的所有类型创建一个
    DataContractSerializer
    ,在反序列化过程中修复/忽略命名空间

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

    • IStateSerializer.Read(BinaryReader)
      中,将序列化数据读取为XML
    • 根据需要更改XML名称空间
    • 将XML馈送到
      DataContractSerializer
      以创建对象
    • 返回对象

    我们将尝试两阶段升级。我们将尝试两阶段升级。