支持对象子类化

https://blueprints.launchpad.net/nova/+spec/object-subclassing

实现对对象子类化的正确支持。如果某个钩子、扩展或替代的 DB API 后端子类化了基础对象中的一个,则应该注册新的对象,并且所有代码都应该使用这个新的类。

问题描述

子类化对象对于实现替代的 DB API 后端可能是必要的。可能还有其他一些用例需要覆盖默认对象行为。之前有一个粗略的计划在主干分支上支持对象子类化。然而,在我们开始着陆当前的全部对象代码之前,它并没有被完全考虑周全。目前所有对象都会被注册,但是没有检查对象所声明的版本。此外,目前所有代码都直接引用 nova/objects 下的基础对象类。

提议的变更

在注册对象时,检查版本以查看它是否已经存在。如果存在,则用新的对象替换跟踪对象列表中的原始对象。在注册对象时,在 nova.objects 模块上设置一个属性,指向对象最新版本的最新类。将所有直接引用 nova/objects 模块下对象类的代码替换为使用 nova.objects 属性的代码。这有一个副作用,可以清理导入。不必导入大量的 nova.object 模块,只需要导入 nova.objects。

注意:此规范不涉及添加一个钩子/入口点来允许替代对象实现。这将在某个时候作为单独的规范提出。目前,可以指定一个替代的 db_backend 并以这种方式注册替代对象实现,但我认为这在长期来看不是正确的方法。

备选方案

设置 nova.objects 模块上的属性有一些替代方案,例如创建一个返回最新对象的方法并在所有地方调用该方法。这将导致略低的性能。我想另一个避免在所有地方更改代码的解决方案是,将所有对象类重命名为 Base<Object>,然后以某种方式将最新版本设置为当前模块上的 <Object>。但是,我更喜欢使用 objects.<Object> 的方式。

数据模型影响

无。

REST API 影响

无。

安全影响

无。

通知影响

无。

其他最终用户影响

无。

性能影响

无。

其他部署者影响

无。

开发人员影响

这些更改会影响很多文件。任何类似于 instance_obj.Instance 的引用都会更改为 objects.Instance。在对象子类化补丁或其他正在审查的补丁中,很可能会出现需要解决的冲突。

新的补丁集不应该导入定义对象的模块来直接引用其中的对象类。应该始终导入 nova.objects 并使用 nova.objects.<Object>。

对象在定义它们的模块被导入时注册自身。有了这个更改,由于可能不需要在代码中使用它们的模块中导入对象模块(而是导入 nova.objects),因此必须确保对象模块在 nova/objects/__init__.py 的 register_all() 方法中导入。

实现

负责人

主要负责人

cbehrens

工作项

  • 修复对象注册,以正确跟踪对象类并在 nova.objects 模块上设置属性

  • 切换代码以使用 nova.objects 模块。这将分解为 nova 的区域,例如 nova/api 和 nova/compute 等。

依赖项

无。

测试

测试将被修改为也使用 nova.objects。

文档影响

无。

参考资料

无。