Orleans 2.0官方文档 —— 6.3.2 部署 -> Grain版本管理 -> 向后兼容性指南

向后兼容性指南

编写向后兼容的代码可能很难,并且难以测试。

永远不要更改现有方法的签名

由于Orleans序列化器的工作方式,您决不应该更改现有方法的签名。

以下示例是正确的:

[Version(1)]
public interface IMyGrain : IGrainWithIntegerKey
{
  // First method
  Task MyMethod(int arg);
}
[Version(2)]
public interface IMyGrain : IGrainWithIntegerKey
{
  // Method inherited from V1
  Task MyMethod(int arg);

  // New method added in V2
  Task MyNewMethod(int arg, obj o);
}

这是不正确的:

[Version(1)]
public interface IMyGrain : IGrainWithIntegerKey
{
  // First method
  Task MyMethod(int arg);
}
[Version(2)]
public interface IMyGrain : IGrainWithIntegerKey
{
  // Method inherited from V1
  Task MyMethod(int arg, obj o);
}

注意:您不应该在代码中进行此更改,因为这是一个导致非常糟糕的副作用的坏实践的示例。这是一个例子,如果只重命名参数名称会发生​​什么,假设我们在集群中部署了以下接口的两个版本:

[Version(1)]
public interface IMyGrain : IGrainWithIntegerKey
{
  // return a - b
  Task<int> Substract(int a, int b);
}
[Version(2)]
public interface IMyGrain : IGrainWithIntegerKey
{
  // return y - x
  Task<int> Substract(int y, int x);
}

这种方法似乎相同。但是如果使用V1调用客户端,并且请求由V2的激活体来处理:

var grain = client.GetGrain<IMyGrain>(0);
var result = await grain.Substract(5, 4); // Will return "-1" instead of expected "1"

这是由于内部的Orleans序列化器的工作原理的缘故。

避免更改现有方法逻辑

这看起来很明显,但在更改现有方法的主体时,应该非常小心。除非您正在修复bug,否则如果需要修改代码,最好只添加一个新方法。

例:

// V1
public interface MyGrain : IMyGrain
{
  // First method
  Task MyMethod(int arg)
  {
    SomeSubRoutine(arg);
  }
}
// V2
public interface MyGrain : IMyGrain
{
  // Method inherited from V1
  // Do not change the body
  Task MyMethod(int arg)
  {
    SomeSubRoutine(arg);
  }

  // New method added in V2
  Task MyNewMethod(int arg)
  {
    SomeSubRoutine(arg);
    NewRoutineAdded(arg);
  }
}

不要从grain接口中删除方法

除非您确定不再使用它们,否则不应从grain接口中删除方法。如果要删除方法,则应分两步完成:

  1. 部署V2 grain,将V1方法标记为 Obsolete

    [Version(1)]
    public interface IMyGrain : IGrainWithIntegerKey
    {
     // First method
     Task MyMethod(int arg);
    }
    
    [Version(2)]
    public interface IMyGrain : IGrainWithIntegerKey
    {
     // Method inherited from V1
     [Obsolete]
     Task MyMethod(int arg);
    
     // New method added in V2
     Task MyNewMethod(int arg, obj o);
    }
    
  2. 如果您确定没有进行V1调用(实际上V1不再部署在正在运行的集群中),在删除v1方法的情况下部署v3。

    [Version(3)]
    public interface IMyGrain : IGrainWithIntegerKey
    {
     // New method added in V2
     Task MyNewMethod(int arg, obj o);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值