开发过程中,碰到流程性质的业务时,可将一个个流程抽象成一个个的执行对象
流程之间会有依赖关系,现在就变成了对象之间的依赖关系
对象的依赖关系如果碰到循环依赖的话整个执行就会变成一个死循环
如果流程特别多,出现循环依赖的话,人工排查就会特别费事
如何在代码中排查循环依赖,并确定哪些地方有循环依赖,直接见代码
def get_dependency_lst():
return [
("A", ["B", "C", "D"]),
("B", ["B", "C", "A"]),
("C", ["D"]),
("D", [])
]
def check_depends_yield(depends_dict, depends_chain, current_idx):
"""使用递归回溯找到所有有循环依赖的的依赖链
:param depends_dict:
:param depends_chain:
:param current_idx:
:return:
"""
if current_idx not in depends_dict:
raise Exception(f"index {current_idx} not in index dict")
if current_idx[-1] in depends_chain[:-1]:
yield depends_chain
print(f"find one cycle depends chain:{depends_chain}")
return
current_depends = depends_dict[current_idx]
for idx in current_depends:
yield from check_depends_yield(depends_dict, depends_chain + (idx,), idx)
def check_depends_del(depends_dict):
"""
循环删除0度依赖来判定是否存在循环依赖
:param depends_dict:
:return:
"""
from copy import deepcopy
depends_dict_cp = deepcopy(depends_dict)
while True:
depend_zero_degree = [k for k, v in depends_dict_cp.items() if not v]
if not depend_zero_degree:
break
for k in depend_zero_degree:
depends_dict_cp.pop(k)
depends_dict_cp = {k: [i for i in v if i not in depend_zero_degree] for k, v in depends_dict_cp.items()}
if not depends_dict_cp:
print("not found cycle depend")
return
print(f"found cycle depends: {depends_dict_cp}")
def check_cycle_dependency():
depends_dict = {item[0]: item[1] for item in get_dependency_lst()}
for index in depends_dict:
ret = []
for chain in check_depends_yield(depends_dict, (index,), index):
ret.append(chain)
if ret:
print(ret)
print('==================\n')
check_depends_del(depends_dict)
if __name__ == "__main__":
check_cycle_dependency()