Python 3.x Python3如何表示引导序列的简单依赖关系图

Python 3.x Python3如何表示引导序列的简单依赖关系图,python-3.x,class,Python 3.x,Class,我的问题是创建一个服务器列表,这些服务器必须按顺序重新启动。比如: 如果server01已经启动,那么server02a和server02b可能会启动,在server02a出现server03之后,等等。因此我创建了类Server并尝试附加一些服务器: #!/usr/bin/env python3 class Server: def __init__(self, name, nextsrv=[]): self.name = name self.next

我的问题是创建一个服务器列表,这些服务器必须按顺序重新启动。比如: 如果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]的下一个TSRV中添加服务器
  • 如何在实例中的列表中循环此列表

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

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
需要一个
\uuuuuuuuu散列方法。服务器仅按名称进行比较。我还添加了对从属服务器的反向引用,以便在服务器可引导时可以轻松地进行检查,即,不在另一个未引导服务器的
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())

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

看起来您试图进行链表设置。为什么不将所有服务器放在一个列表中,然后遍历该列表,按顺序引导服务器呢?为什么有
self.nextsrv
?@Carcigenicate。因为有些服务器可能需要更长的启动时间,但其他服务器不会依赖它们。@Madh物理学家啊,我想这是有道理的。第二个类具有多个“依赖链”(列表),然后将相互依赖的服务器附加到每个列表中可能更容易。我可以看到通过内部列表链接实例变得混乱。名义上,您可以使用列表来描述依赖关系:
[['server01']、['server02a'、['server02b']、['server03']]
,甚至在配置文件中创建一个列表。您是否需要更复杂的内容取决于您希望如何使用数据。例如,这些依赖关系是如何决定的,以及您希望如何使用这些数据。非常感谢!这个完整的答案在很大程度上帮助了我。制作一本字典“服务器”(而不是列表)也是一个很好的建议。@RJAlten,很高兴它奏效了。向上投票也不错。