Python3 append如何表示引导序列的简单依赖关系图



我的问题是创建一个服务器列表,这些服务器必须按顺序重新启动。喜欢:如果server01已经启动,那么server02a和server02b可能会启动,在server02a之后是server03,等等。所以我创建了类Server,并尝试添加一些服务器:

#!/usr/bin/env python3
class Server:
def __init__(self, name, nextsrv=[]):
self.name = name
self.nextsrv = nextsrv
print(self.name)
servers = []
servers.append(Server('server01'))
servers.append(Server('serverXX'))
servers[0].nextsrv.append(Server('server02a'))
  • 如何添加更多实例?不接受下一个服务器server02b
  • 如何在server02[ab]的nextsrv中添加服务器
  • 如何在实例中的列表中循环此列表

我将维护两种不同的结构:服务器及其依赖项的树,以及当前启动服务器的列表。这将涉及到稍微扩展服务器类,以允许更复杂的图形结构:

class Server:
def __init__(self, name, nextsrv=None):
self.name = name
self.booted = False
self.nextsrv = set()
if nextsrv is not None:
self.add_srvs(nextsrv)
def __eq__(self, other):
return isinstance(other, Server) and self.name == other.name
def __hash__(self):
return hash(self.name)
def boot(self):
# Do some magic here
self.booted = True
def add_srv(self, srv):
self.nextsrv.add(srv)
srv.depends.add(self)
def add_srvs(self, srvs):
for srv in srvs:
self.add_srv(srv)
def has_depends(self):
for srv in self.depends:
if not srv.booted:
return True
return False

我已经把nextsrv变成了一个集合,这意味着Server需要一个__hash__方法。服务器仅按名称进行比较。我还添加了对从属服务器的反向引用,这样就可以很容易地检查服务器何时可以启动,即不在另一个未启动服务器的nextsrv列表中。

现在,您可以按照所述设置服务器树。我只想做一个格言,让你做一些类似的事情:

servers = {}
servers['server03'] = Server('server03')
servers['server02a'] = Server('server02a', servers['server03'])
servers['server02b'] = Server('server02b')
servers['server01'] = Server('server01', [x for x in servers.values() if x.name in ('server02a', 'server02b')])

您可以将每个服务器分配给不同的变量,但我认为通过dict管理许多不同的服务器更容易。它还允许您自动计算引导序列:

from collections import deque
# Startup: find all servers that no-one depends on
boot_candidates = deque((x for x in servers.items if not x.depends))
# Iteration with for will break if we extend the list during iteration
while boot_candidates:
srv = boot_candidates.popleft()
srv.boot()
boot_candidates.extend(x for x in srv.nextsrv if not x.hasdepends())

此解决方案不检查循环依赖关系和其他复杂性。然而,它确实具有高度可并行性的优势,这可能是您应该研究的问题,尤其是因为启动服务器应该消耗本地机器上的很少资源(除非您有VM)。

最新更新