Hazelcast VersionedPortalble 的使用
Usage of Hazelcast VersionedPortalble
我正在研究 Hazelcast 中的可移植序列化。特别是,我对 VersionedPortable
接口很感兴趣。我创建了一个场景,其中两个客户端具有相同 class:
的不同版本
//VERSION 1
public class Vehicle implements VersionedPortable {
private final String type;
public Vehicle() { this.type = ""; }
public Vehicle(final String type) { this.type = type; }
public void setType(final String type) { this.type = type; }
public String getType () { return this.type; }
public void writePortable(PortableWriter writer) throws IOException {
writer.writeUTF("type", type);
}
public void readPortable(PortableReader reader) throws IOException {
type = reader.readUTF("type");
}
public int getFactoryId() { return 1; }
public int getClassId() { return 1; }
public int getClassVersion () { return 1;}
}
//VERSION 2
public class Vehicle implements VersionedPortable {
private final String type;
private final int tyres;
public Vehicle() { this.type = ""; this tyres = 0;}
public Vehicle(final String type, final int tyres) { this.type = type; this.tyres = tyres; }
public void setType(final String type) { this.type = type; }
public String getType () { return this.type; }
public void writePortable(PortableWriter writer) throws IOException {
writer.writeUTF("type", type);
writer.writeInt("tyres", tyres);
}
public void readPortable(PortableReader reader) throws IOException {
type = reader.readUTF("type");
tyres = reader.readInt("tyres");
}
public int getFactoryId() { return 1; }
public int getClassId() { return 1; }
public int getClassVersion () { return 2;}
}
我在以下场景中使用了这两个 class:
- 具有 V1 的 Hazelcast 客户端创建车辆并将其存储在 IMap 中:type=Porsche
- 带有 V2 的 Hazelcast 客户端更新车辆并将其存储在 IMap 中:轮胎=4
- 带有 V1 的 Hazelcast 客户端更新车辆并将其存储在 IMap 中:type=Audi
- 带有 V2 的 Hazelcast 客户端读取车辆并将其打印到控制台:预期:奥迪,4;得到:奥迪,0
我的期望错了吗?我开始怀疑 VersionedPortable 并不符合我的预期(支持在单个 IMap 中读取和写入同一对象的不同版本)。
Github (line 95) and another SO-post 上的一些代码(参见第三个项目符号)似乎指向那个方向。
您提到的另一个 post 是正确的——您的 V1 代码只知道类型字段,因此 V1 所做的任何写入都只会写入类型字段而不是轮胎字段。由于您的 V1 对象不知道轮胎,它不会保留 V2 代码在上一次更新期间写入的值。
好消息是您的 V1 代码无需任何修改即可读取 V2 代码编写的对象。 (注意:编辑为正确的声明,V1 可以读取 V2 写入的对象,我打错了,说写在原文中)
V2 代码需要注意,只要 V1 客户端仍然是系统的一部分,它就必须准备好看到那里没有价值的条目。设置默认值以在找不到值时使用可能很有用。
在某些情况下,您可能希望强制执行限制,即 reader 检查正在读取的对象的版本,如果它来自更高版本的代码,则禁止更新对象。通过这种方式,您可以确保不会丢失更新代码的更新,可能会抛出异常,导致用户看到警告或错误,表明它们不是 运行 最新的客户端代码,应该更新以便对请求的对象具有写访问权限。
我正在研究 Hazelcast 中的可移植序列化。特别是,我对 VersionedPortable
接口很感兴趣。我创建了一个场景,其中两个客户端具有相同 class:
//VERSION 1
public class Vehicle implements VersionedPortable {
private final String type;
public Vehicle() { this.type = ""; }
public Vehicle(final String type) { this.type = type; }
public void setType(final String type) { this.type = type; }
public String getType () { return this.type; }
public void writePortable(PortableWriter writer) throws IOException {
writer.writeUTF("type", type);
}
public void readPortable(PortableReader reader) throws IOException {
type = reader.readUTF("type");
}
public int getFactoryId() { return 1; }
public int getClassId() { return 1; }
public int getClassVersion () { return 1;}
}
//VERSION 2
public class Vehicle implements VersionedPortable {
private final String type;
private final int tyres;
public Vehicle() { this.type = ""; this tyres = 0;}
public Vehicle(final String type, final int tyres) { this.type = type; this.tyres = tyres; }
public void setType(final String type) { this.type = type; }
public String getType () { return this.type; }
public void writePortable(PortableWriter writer) throws IOException {
writer.writeUTF("type", type);
writer.writeInt("tyres", tyres);
}
public void readPortable(PortableReader reader) throws IOException {
type = reader.readUTF("type");
tyres = reader.readInt("tyres");
}
public int getFactoryId() { return 1; }
public int getClassId() { return 1; }
public int getClassVersion () { return 2;}
}
我在以下场景中使用了这两个 class:
- 具有 V1 的 Hazelcast 客户端创建车辆并将其存储在 IMap 中:type=Porsche
- 带有 V2 的 Hazelcast 客户端更新车辆并将其存储在 IMap 中:轮胎=4
- 带有 V1 的 Hazelcast 客户端更新车辆并将其存储在 IMap 中:type=Audi
- 带有 V2 的 Hazelcast 客户端读取车辆并将其打印到控制台:预期:奥迪,4;得到:奥迪,0
我的期望错了吗?我开始怀疑 VersionedPortable 并不符合我的预期(支持在单个 IMap 中读取和写入同一对象的不同版本)。
Github (line 95) and another SO-post 上的一些代码(参见第三个项目符号)似乎指向那个方向。
您提到的另一个 post 是正确的——您的 V1 代码只知道类型字段,因此 V1 所做的任何写入都只会写入类型字段而不是轮胎字段。由于您的 V1 对象不知道轮胎,它不会保留 V2 代码在上一次更新期间写入的值。
好消息是您的 V1 代码无需任何修改即可读取 V2 代码编写的对象。 (注意:编辑为正确的声明,V1 可以读取 V2 写入的对象,我打错了,说写在原文中)
V2 代码需要注意,只要 V1 客户端仍然是系统的一部分,它就必须准备好看到那里没有价值的条目。设置默认值以在找不到值时使用可能很有用。
在某些情况下,您可能希望强制执行限制,即 reader 检查正在读取的对象的版本,如果它来自更高版本的代码,则禁止更新对象。通过这种方式,您可以确保不会丢失更新代码的更新,可能会抛出异常,导致用户看到警告或错误,表明它们不是 运行 最新的客户端代码,应该更新以便对请求的对象具有写访问权限。