- 需求
- 设计理念
- 抽象一个(仅仅一个)状态的改变为一个步骤,也即是说步骤是一个状态变更
- 将步骤按一定顺序串起组成整个原子
- 每个步骤又分为两个部分
- 收集当前的状态数据,并更新状态中的旧状态
- 执行
- 收集当前的状态数据,并更新状态中的新状态
- 整个原子支持在执行原子之前操作和之后的操作,这两个操作都支持回滚,比如发版前关闭实例流量,发版完成后打开实例流量;当然这种操作也可以放到原子中,看场景和便捷性;
- 注意
- 一个真正的流水线上的原子设计,还有好多东西需要抽象;一个通用又灵活的流水线的原子,有更多的东西需要抽象;这里仅仅提供原子执行失败之后回滚功能的实现框架
- 另外下面的代码提供了一个check_common函数,当某个状态变更(步骤)失败时,需要再次验证(或者说是确认)状态是否改变,会更严谨
class base_atom:
def atom_pre(self):
pass
def atom_pre_undo(self):
pass
def atom(self):
raise NotImplementError("atom方法必须要重写")
def atom_post(self):
pass
def atom_post_undo(self):
pass
class AtomError(Exception):
def __init__(self,msg):
self.message = msg
def __str__(self):
return self.message
class deploy_atom(base_atom):
def __init__(self,states):
self.change_list = ["first","second","third", "fourth"]
self.states = []
self.ret = {"result": None}
def first_step(self):
print("exec first step!")
def first_undo(self):
print("undo first step!")
def second_step(self):
print("exec second step!")
def second_undo(self):
print("undo second step!")
def third_step(self):
print("exec three step!")
def third_undo(self):
print("undo three step!")
def fourth_step(self):
print("exec four step!")
def fourth_undo(self):
print("undo four step!")
def check_common(self):
pass
def atom(self):
exec_tail = []
exec_ret,undo_ret = "success", ""
exec_step = 0
for n,exec in enumerate(self.change_list):
try:
if n == 2:
raise AtomError("Just a test")
target = getattr(self, exec + "_step", None)
target()
except Exception as e:
exec_ret = "fail"
print("exec_ret: {}".format(exec_ret))
break
else:
exec_tail.append(exec)
if exec_ret == "fail":
undo_ret = "successful"
while(len(exec_tail) > 0):
last_step = exec_tail.pop()
try:
target = getattr(self, last_step + "_undo", None)
target()
except Exception as e:
undo_ret = "fail"
pass
break
self.ret = {"result": exec_ret, "undo_ret": undo_ret}
return self.ret
deploy = deploy_atom({"name": "abc-test-api"})
deploy.atom()