Watcher Planner Selector
This component is responsible for selecting an appropriate Planner based on config options passed by user for distinct Strategy. Change-Id: I8dd84cef4b9eb25a6cdf448d55a2dd8da3f10f9c Implements: bp watcher-planner-selector
This commit is contained in:
parent
d939277b9f
commit
bff4227aed
218
specs/rocky/approved/watcher-planner-selector.rst
Normal file
218
specs/rocky/approved/watcher-planner-selector.rst
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
..
|
||||||
|
This work is licensed under a Creative Commons Attribution 3.0 Unported
|
||||||
|
License.
|
||||||
|
|
||||||
|
http://creativecommons.org/licenses/by/3.0/legalcode
|
||||||
|
|
||||||
|
========================
|
||||||
|
Watcher Planner Selector
|
||||||
|
========================
|
||||||
|
|
||||||
|
https://blueprints.launchpad.net/watcher/+spec/watcher-planner-selector
|
||||||
|
|
||||||
|
`Watcher Planner`_ takes the set of `Actions`_ generated by a `Strategy`_ and
|
||||||
|
builds the design of a workflow which defines how-to schedule in time those
|
||||||
|
different Actions and for each Action what are the prerequisite conditions.
|
||||||
|
It is only possible to choose only one (default) `Planner`_ for all strategies
|
||||||
|
now.
|
||||||
|
|
||||||
|
Custom Planners could be added to Watcher, thereby users can adapt Watcher
|
||||||
|
workflow to their needs. As one of the ways for customization, the option
|
||||||
|
could be added to set concrete Planner for specific Strategy that takes
|
||||||
|
features of users' workflow into account.
|
||||||
|
|
||||||
|
|
||||||
|
Problem description
|
||||||
|
===================
|
||||||
|
|
||||||
|
Currently there is no opportunity to set unique Planner to specific Strategy.
|
||||||
|
User can set default Planner in config file that would be used alongside every
|
||||||
|
Audit.
|
||||||
|
|
||||||
|
If using different Planner is the case, user should change default
|
||||||
|
value to desired one. By doing this we restrict ourselves to use this new
|
||||||
|
Planner with all of the Strategies, what is not desired because some of
|
||||||
|
`Solutions`_ generated by Strategies could be not compatible with the schedule
|
||||||
|
made by this Planner.
|
||||||
|
|
||||||
|
Use Cases
|
||||||
|
----------
|
||||||
|
|
||||||
|
* As an Strategy developer, I want to choose what Planner would be applied to the
|
||||||
|
Solution generated by my Strategy.
|
||||||
|
|
||||||
|
* As an Strategy developer, I expect that if I provide no Planner to my Strategy, it
|
||||||
|
will use default Planner that is set in base Strategy..
|
||||||
|
|
||||||
|
|
||||||
|
Proposed change
|
||||||
|
===============
|
||||||
|
|
||||||
|
We propose to add property to base Strategy class, say 'planner', and set
|
||||||
|
default value to this option in concrete Strategies where appropriate (for
|
||||||
|
example, 'workload_stabilization' Planner as default for Strategy with the
|
||||||
|
same name).
|
||||||
|
|
||||||
|
Planner should be load in AuditHandler. Currently it's done with the help of
|
||||||
|
PlannerManager, that loads sole planner for every Strategy which set by
|
||||||
|
CONF.watcher_planner.planner value. Definitely, PlannerManager do only
|
||||||
|
loading job, so it's better to load Planner without this intermediate layer.
|
||||||
|
Thus we propose to exchange AuditHandler._planner_manager with
|
||||||
|
DefaultPlannerLoader. As a result, PlannerManager could be removed from
|
||||||
|
Watcher.
|
||||||
|
|
||||||
|
Therefore, AuditHandler now should pass desired Planner name to Loader.
|
||||||
|
We propose to get this name from property of the Strategy used in current
|
||||||
|
Audit. In this case we ought to get Strategy object associated with current
|
||||||
|
Audit.
|
||||||
|
|
||||||
|
For this propose, we need to be able to get Strategy prior to
|
||||||
|
AuditHandler._planner_loader.load() method call. It could be be done with the
|
||||||
|
help of StrategyContext class that loads Strategy based on names of Goal and
|
||||||
|
Audit. The problem is that this loading is done during do_execute_strategy()
|
||||||
|
what's a bad design. We propose to move *selecting* of strategy to distinct
|
||||||
|
method, say '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()
|
||||||
|
|
||||||
|
Now we could call this method not only in do_execute_strategy() to pick
|
||||||
|
strategy only for execution, but also call it in AuditHandler.
|
||||||
|
|
||||||
|
Another benefit to do it in this manner is that if Audit was created without
|
||||||
|
specified Strategy, StrategyContext will take care to retrieve default
|
||||||
|
Strategy for this Goal.
|
||||||
|
|
||||||
|
By design, whole AuditHandler class passes current Audit as an argument of
|
||||||
|
many of its methods. It would be convenient to have current Audit as a field of
|
||||||
|
AuditHandler class. Also, it is good design decision, because it's true OOP
|
||||||
|
paradigm. To sum up, we propose to remove all these arguments and replace
|
||||||
|
them with class field.
|
||||||
|
|
||||||
|
As a result, we can get Planner for current Strategy without adding new
|
||||||
|
argument to AuditHandler.planner() or storing name of Strategy in additional
|
||||||
|
field.
|
||||||
|
|
||||||
|
Alternatives
|
||||||
|
------------
|
||||||
|
|
||||||
|
Alternatively, we could pass Planner name as argument during creation of
|
||||||
|
AuditTemplate.
|
||||||
|
|
||||||
|
As an alternative to changing signatures of AuditHandler methods we could add a
|
||||||
|
new field only for Strategy name.
|
||||||
|
|
||||||
|
Data model impact
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
REST API impact
|
||||||
|
---------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Security impact
|
||||||
|
---------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Notifications impact
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Other end user impact
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Performance Impact
|
||||||
|
------------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Other deployer impact
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Developer impact
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Signature of PlannerManager.load() method changes.
|
||||||
|
AuditHandler methods change their signatures, 'audit' argument would be
|
||||||
|
replaced with same class field.
|
||||||
|
|
||||||
|
|
||||||
|
Implementation
|
||||||
|
==============
|
||||||
|
|
||||||
|
Assignee(s)
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Primary assignee:
|
||||||
|
Egor Panfilov <erakli>
|
||||||
|
|
||||||
|
Work Items
|
||||||
|
----------
|
||||||
|
|
||||||
|
* Refactor DefaultStrategyContext.do_execute_strategy() and add
|
||||||
|
select_strategy() method
|
||||||
|
* Add 'planner' property to BaseStrategy
|
||||||
|
* Replace PlannerManager with PlannerLoader in AuditHandler
|
||||||
|
* Rewrite AuditHandler methods so that 'audit' argument would be replaced
|
||||||
|
with class' field
|
||||||
|
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
============
|
||||||
|
|
||||||
|
https://blueprints.launchpad.net/watcher/+spec/planner-storage-action-plan
|
||||||
|
|
||||||
|
|
||||||
|
Testing
|
||||||
|
=======
|
||||||
|
|
||||||
|
Tests with different Planners assigned to different Strategies should be
|
||||||
|
implemented.
|
||||||
|
|
||||||
|
|
||||||
|
Documentation Impact
|
||||||
|
====================
|
||||||
|
|
||||||
|
Documentation should be updated to explain how to set 'planner' option.
|
||||||
|
|
||||||
|
|
||||||
|
References
|
||||||
|
==========
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
|
||||||
|
History
|
||||||
|
=======
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
|
||||||
|
.. _Actions: https://docs.openstack.org/watcher/latest/glossary.html#action
|
||||||
|
.. _Strategy: https://docs.openstack.org/watcher/latest/glossary.html#strategy
|
||||||
|
.. _Solutions: https://docs.openstack.org/watcher/latest/glossary.html#solution
|
||||||
|
.. _Planner: https://docs.openstack.org/watcher/latest/glossary.html#watcher-planner
|
||||||
|
.. _Watcher Planner: https://docs.openstack.org/watcher/latest/glossary.html#watcher-planner
|
Loading…
Reference in New Issue
Block a user