Add several tokens to control events between resources

This commit is contained in:
Dmitry Shulyak 2015-07-30 18:04:36 +03:00
parent cfa6c7be72
commit 6451f62628
5 changed files with 103 additions and 22 deletions

View File

@ -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

View File

View 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

View File

@ -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',

View File

@ -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