Service Deployment ConfigsΒΆ

Each EI service has a deployment configuration, and we automate these via _EISvc class instances that are used by an EI manager. Functions in these classes can be set to run on all nodes in an EI manager, or instead take a specific node instance as an argument.

For example, take the PubSub service configuration:

class PubSub(_EISvc):
SVCID = 3
SVCNAME = "pubsub"

def __init__(self, ei):
    super().__init__(ei)
    self.cores = [node for node in ei.nodes if node.sn == 3]

@splat_node
def config(self, *, node):
    ctl = QuickCtl(node)
    res = MiniFutureList()
    res.append(ctl.call('tree.add_child', 'config', './"services"/"pubsub"'))
    res.append(
        ctl.call('tree.add_child', 'config', './"services"/"pubsub"/"core_sn_id"')
    )
    res.append(
        ctl.call(
            'tree.write', 'config', './"services"/"pubsub"/"core_sn_id"', value=3
        )
    )
    return res

@splat_node
def start_proxy(self, *, node):
    return node.node.run(
        f'cd {node.node.pox_dir} ; ./pox.py misc.pidfile=/tmp/eilogs/pid_{node.dom}_{node.sn}_pubsub_proxy web --no-cookieguard --port={node.proxy_port(self.SVCID)} ei.pubsub.proxy --hssock={node.hssock} >&/dev/null &',
        asynchronous=True,
    )

The SVCID and SVCNAME variables must match what is in EI directly. By defining the @splat_node decorator on the config(...) and start_proxy(...) functions, the EI manager can run this function on all nodes:

ei.pubsub.config()
ei.pubsub.start_proxy()
node_mgr.wait_all()

The futures list in these functions will cause the commands added onto a node to be run in-order on that node; each node has an asynchronous task manager to do this. Running wait_all() on a node manager will wait for all commands on all nodes to complete before returning.

It is possible to write these functions without @splat_node, in which case they must be called with a service node instance:

ei.qbss.config(node=node_mgr.instance((1, 1)), ...)