Add several tokens to control events between resources
This commit is contained in:
parent
93f92e3c07
commit
4021260a75
@ -24,11 +24,11 @@ Propagating events when there is no data changed
|
||||
|
||||
Control for specifying events:
|
||||
|
||||
on <emitter>.<emmiter_action> <event> <subscriber>.<subsciber_action>
|
||||
on <emitter>.<emmiter_action> <event> <subscriber>.<subsciber_action>
|
||||
|
||||
# on mariadb.run changed keystone.run
|
||||
# on keystone.run changed keystone_config.run
|
||||
# on keystone_config.run changed haproxy.reload
|
||||
on mariadb.run changed keystone.run
|
||||
on keystone.run changed keystone_config.run
|
||||
on keystone_config.run changed haproxy.reload
|
||||
|
||||
+---------------------+
|
||||
| mariadb.run |
|
||||
@ -46,13 +46,13 @@ Control for specifying events:
|
||||
| haproxy.reload |
|
||||
+---------------------+
|
||||
|
||||
<u> - <event>:<action> - <v>
|
||||
<u>.<action> - <event> - <v>.<action>
|
||||
|
||||
When connection between several resources created - events connections should
|
||||
When data connection between several resources created - events connections should
|
||||
be created as well, resource a connect resource b:
|
||||
|
||||
on a changed b reload
|
||||
on a removed b run
|
||||
on a.run changed b.reload
|
||||
on a.remove changed b.run
|
||||
|
||||
-------------------------------------------------
|
||||
Resolving cycles on a data plane
|
||||
@ -73,9 +73,9 @@ rmq.2.cluster_join, rmq.2.cluster_join
|
||||
|
||||
Also cluster operation should happen only when rmq.cluster is changed.
|
||||
|
||||
on rmq.cluster changed rmq.1 cluster_create
|
||||
on rmq.1.cluster_create changed rmq.2 cluster_join
|
||||
on rmq.1.cluster_create changed rmq.3 cluster_join
|
||||
on rmq.cluster changed rmq.1.cluster_create
|
||||
on rmq.1.cluster_create changed rmq.2.cluster_join
|
||||
on rmq.1.cluster_create changed rmq.3.cluster_join
|
||||
|
||||
+----------------------+
|
||||
| rmq.1.run |
|
||||
@ -102,7 +102,7 @@ on rmq.1.cluster_create changed rmq.3 cluster_join
|
||||
| rmq.3.run | |
|
||||
+----------------------+ |
|
||||
| |
|
||||
| cahnged |
|
||||
| changed |
|
||||
v |
|
||||
+----------------------+ |
|
||||
| rmq.3.cluster_join | <+
|
||||
@ -113,7 +113,7 @@ on rmq.1.cluster_create changed rmq.3 cluster_join
|
||||
---------------------------------------------------
|
||||
Resolve cycles on a execution level
|
||||
|
||||
Lets say we have 5 objects, which forms 2 pathes
|
||||
We have 5 objects, which forms 2 pathes
|
||||
- keystone-config -> keystone-service -> haproxy-sevice
|
||||
- glance-config -> glance-service -> haproxy-service
|
||||
|
||||
|
0
solar/solar/events/__init__.py
Normal file
0
solar/solar/events/__init__.py
Normal file
75
solar/solar/events/control.py
Normal file
75
solar/solar/events/control.py
Normal file
@ -0,0 +1,75 @@
|
||||
"""
|
||||
Available controls:
|
||||
|
||||
*depends_on* implements relationship that will guarantee that depended action
|
||||
on resource will be executed after parent, if parent will be executed. It means
|
||||
that this control contributes only to ordering, and wont trigger any action
|
||||
if dependent resource isnt changed.
|
||||
|
||||
depends_on:
|
||||
- parent:run -> ok -> dependent:run
|
||||
|
||||
*react_on* - relationship which will guarantee that action on dependent resource
|
||||
will be executed if parent action is going to be executed. This control will
|
||||
trigger action even if no changes noticed on dependent resource.
|
||||
|
||||
react_on:
|
||||
- parent:update -> ok -> dependent:update
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from solar.core.log import log
|
||||
|
||||
|
||||
EVENT = re.compile(r'\s+->\s+')
|
||||
|
||||
|
||||
class Event(object):
|
||||
|
||||
def __init__(self, event):
|
||||
self.parent, self.dependent, self.state = EVENT.split(event)
|
||||
self.parent_node, self.parent_action = self.parent.split(':')
|
||||
self.dep_node, self.dep_action = self.dependent.split(':')
|
||||
|
||||
def __repr__(self):
|
||||
return '{}({} -> {} -> {})'.format(
|
||||
self.__class__.__name__,
|
||||
self.parent, self.dependent, self.state)
|
||||
|
||||
|
||||
class Dependency(Event):
|
||||
|
||||
def add(self, changed_resources, changes_graph):
|
||||
if self.parent in changes_graph:
|
||||
changes_graph.add_edge(
|
||||
self.parent, self.dependent, state=self.state)
|
||||
|
||||
|
||||
class React(Event):
|
||||
|
||||
def add(self, changed_resources, changes_graph):
|
||||
changes_graph.add_edge(self.parent, self.dependent, state=self.state)
|
||||
changed_resources.append(self.dep_node)
|
||||
|
||||
|
||||
def build_edges(changed_resources, changes_graph, events):
|
||||
"""
|
||||
:param changed_resources: list of resource names that were changed
|
||||
:param changes_graph: nx.DiGraph object with actions to be executed
|
||||
:param events:
|
||||
"""
|
||||
stack = changed_resources[:]
|
||||
while stack:
|
||||
node = stack.pop()
|
||||
events_objects = []
|
||||
|
||||
if node in events:
|
||||
log.debug('Events %s for resource %s', events[node], node)
|
||||
|
||||
for e in events[node].get('react_on', ()):
|
||||
React(e).add(stack, changes_graph)
|
||||
for e in events[node].get('depends_on', ()):
|
||||
Dependency(e).add(stack, changes_graph)
|
||||
|
||||
return changes_graph
|
@ -10,7 +10,7 @@ from solar import errors
|
||||
class RedisDB(object):
|
||||
COLLECTIONS = Enum(
|
||||
'Collections',
|
||||
'connection resource state_data state_log'
|
||||
'connection resource state_data state_log events'
|
||||
)
|
||||
DB = {
|
||||
'host': 'localhost',
|
||||
|
@ -3,6 +3,7 @@ import networkx as nx
|
||||
from pytest import fixture
|
||||
|
||||
|
||||
|
||||
@fixture
|
||||
def simple():
|
||||
dg = nx.DiGraph()
|
||||
@ -10,24 +11,29 @@ def simple():
|
||||
dg.add_edge('keystone_config.run', 'haproxy.reload', event='changed')
|
||||
return dg
|
||||
|
||||
|
||||
def test_simple(simple):
|
||||
nx.write_dot(simple, 'simple.dot')
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@fixture
|
||||
def rmq():
|
||||
"""Example of a case when we have cycles on a data plane."""
|
||||
dg = nx.DiGraph()
|
||||
dg.add_edge('rmq.1.run', 'rmq.1.cluster_create', event='changed')
|
||||
dg.add_edge('rmq.1.cluster_create', 'rmq.2.cluster_join', event='changed')
|
||||
dg.add_edge('rmq.1.cluster_create', 'rmq.3.cluster_join', event='changed')
|
||||
dg.add_edge('rmq.2.run', 'rmq.2.cluster_join', event='changed')
|
||||
dg.add_edge('rmq.3.run', 'rmq.3.cluster_join', event='changed')
|
||||
dg.add_edge('rmq_cluster.run', 'rmq_cluster.1.create', event='changed')
|
||||
dg.add_edge('rmq_cluster.run', 'rmq_cluster.2.join', event='changed')
|
||||
dg.add_edge('rmq_cluster.run', 'rmq_cluster.3.join', event='changed')
|
||||
dg.add_edge('rmq.1.run', 'rmq_cluster.1.create', event='changed')
|
||||
dg.add_edge('rmq.2.run', 'rmq_cluster.2.join', event='changed')
|
||||
dg.add_edge('rmq.3.run', 'rmq_cluster.3.join', event='changed')
|
||||
dg.add_edge('rmq_cluster.1.create', 'rmq_cluster.2.join', event='changed')
|
||||
dg.add_edge('rmq_cluster.1.create', 'rmq_cluster.3.join', event='changed')
|
||||
return dg
|
||||
|
||||
|
||||
def test_rmq(rmq):
|
||||
nx.write_dot(rmq, 'rmq.dot')
|
||||
pass
|
||||
|
||||
|
||||
@fixture
|
||||
@ -43,4 +49,4 @@ def haproxy():
|
||||
|
||||
|
||||
def test_haproxy(haproxy):
|
||||
nx.write_dot(haproxy, 'haproxy.dot')
|
||||
pass
|
||||
|
Loading…
Reference in New Issue
Block a user