Watcher Planner 选择器¶
https://blueprints.launchpad.net/watcher/+spec/watcher-planner-selector
Watcher Planner 接收由 Strategy 生成的一组 Actions,并构建工作流的设计,定义如何在时间上调度这些 Actions,以及每个 Action 的先决条件。目前,只能为所有策略选择一个(默认)Planner。
可以向 Watcher 添加自定义 Planner,从而用户可以根据自己的需求调整 Watcher 工作流。作为定制的一种方式,可以添加为特定 Strategy 设置具体 Planner 的选项,该选项考虑了用户工作流的特性。
问题描述¶
当前没有为特定 Strategy 设置唯一 Planner 的机会。用户可以在配置文件中设置默认 Planner,该 Planner 将与每次 Audit 一起使用。
如果需要使用不同的 Planner,用户应该将默认值更改为所需的值。通过这样做,我们将自己限制为将这个新的 Planner 与所有 Strategy 一起使用,这并非期望的结果,因为由 Strategy 生成的一些 Solutions 可能与该 Planner 制定的调度不兼容。
用例¶
作为 Strategy 开发人员,我希望能够选择将哪个 Planner 应用于我的 Strategy 生成的 Solution。
作为 Strategy 开发人员,我期望如果我的 Strategy 没有提供 Planner,它将使用在基础 Strategy 中设置的默认 Planner。
提议的变更¶
我们建议在基础 Strategy 类中添加一个属性,例如 ‘planner’,并在适当的特定 Strategy 中设置此选项的默认值(例如,对于名称相同的 Strategy,将 ‘workload_stabilization’ Planner 作为默认值)。
Planner 应该在 AuditHandler 中加载。目前,这是通过 PlannerManager 完成的,它为每个 Strategy 加载由 CONF.watcher_planner.planner 值设置的唯一 Planner。显然,PlannerManager 仅执行加载工作,因此最好在没有这个中间层的情况下加载 Planner。因此,我们建议用 DefaultPlannerLoader 替换 AuditHandler._planner_manager。结果是,PlannerManager 可以从 Watcher 中删除。
因此,AuditHandler 现在应该将所需的 Planner 名称传递给 Loader。我们建议从用于当前 Audit 的 Strategy 的属性中获取此名称。在这种情况下,我们需要获取与当前 Audit 关联的 Strategy 对象。
为此,我们需要能够在调用 AuditHandler._planner_loader.load() 方法之前获取 Strategy。这可以通过 StrategyContext 类来完成,该类基于 Goal 和 Audit 的名称加载 Strategy。问题是,这个加载是在 do_execute_strategy() 期间完成的,这是一种糟糕的设计。我们建议将 *选择* Strategy 的操作移动到不同的方法,例如 ‘select_strategy’。
def select_strategy(audit, request_context):
osc = clients.OpenStackClients()
goal = objects.Goal.get_by_id(request_context, audit.goal_id)
strategy_name = None
if audit.strategy_id:
strategy = objects.Strategy.get_by_id(
request_context, audit.strategy_id)
strategy_name = strategy.name
strategy_selector = default.DefaultStrategySelector(
goal_name=goal.name,
strategy_name=strategy_name,
osc=osc)
return strategy_selector.select()
现在我们可以在 do_execute_strategy() 中调用这个方法,以便仅为执行选择 Strategy,也可以在 AuditHandler 中调用它。
以这种方式进行操作的另一个好处是,如果 Audit 是在没有指定 Strategy 的情况下创建的,StrategyContext 将负责检索该 Goal 的默认 Strategy。
从设计上讲,整个 AuditHandler 类将当前的 Audit 作为其许多方法的参数传递。将当前的 Audit 作为 AuditHandler 类的一个字段会很方便。此外,这是一个良好的设计决策,因为它符合真正的 OOP 范例。总而言之,我们建议删除所有这些参数,并用类字段替换它们。
结果是,我们可以为当前的 Strategy 获取 Planner,而无需向 AuditHandler.planner() 添加新的参数,或在额外的字段中存储 Strategy 的名称。
备选方案¶
或者,我们可以在创建 AuditTemplate 时将 Planner 名称作为参数传递。
作为更改 AuditHandler 方法签名的替代方案,我们可以添加一个新的字段,仅用于 Strategy 名称。
数据模型影响¶
无
REST API 影响¶
无
安全影响¶
无
通知影响¶
无
其他最终用户影响¶
无
性能影响¶
无
其他部署者影响¶
无
开发人员影响¶
PlannerManager.load() 方法的签名会发生变化。AuditHandler 方法会更改其签名,‘audit’ 参数将被替换为相同的类字段。
实现¶
负责人¶
- 主要负责人
Egor Panfilov <erakli>
工作项¶
重构 DefaultStrategyContext.do_execute_strategy() 并添加 select_strategy() 方法
向 BaseStrategy 添加 ‘planner’ 属性
用 PlannerLoader 替换 AuditHandler 中的 PlannerManager
重写 AuditHandler 方法,以便将 ‘audit’ 参数替换为类字段
依赖项¶
https://blueprints.launchpad.net/watcher/+spec/planner-storage-action-plan
测试¶
应该实现使用不同 Planner 分配给不同 Strategy 的测试。
文档影响¶
应该更新文档,以解释如何设置 ‘planner’ 选项。
参考资料¶
无
历史¶
无