Пример #1
0
    def __init__(self):
        BuiltinCore.__init__(self)

        #: A dict of child name -> one end of the
        #: :class:`multiprocessing.Pipe` object used to communicate
        #: with that child.  (The child is given the other end of the
        #: Pipe.)
        self.pipes = dict()

        #: A queue that keeps track of which children are available to
        #: render a configuration.  A child is popped from the queue
        #: when it starts to render a config, then it's pushed back on
        #: when it's done.  This lets us use a blocking call to
        #: :func:`Queue.Queue.get` when waiting for an available
        #: child.
        self.available_children = \
            Queue(maxsize=Bcfg2.Options.setup.core_children)

        #: The flag that indicates when to stop child threads and
        #: processes
        self.terminate = DualEvent(threading_event=self.terminate)

        #: A :class:`Bcfg2.Server.MultiprocessingCore.RPCQueue` object
        #: used to send or publish commands to children.
        self.rpc_q = RPCQueue()

        #: A list of children that will be cycled through
        self._all_children = []

        #: An iterator that each child will be taken from in sequence,
        #: to provide a round-robin distribution of render requests
        self.children = None
Пример #2
0
    def shutdown(self):
        BuiltinCore.shutdown(self)
        self.logger.info("Closing RPC command queues")
        self.rpc_q.close()

        def term_children():
            """ Terminate all remaining multiprocessing children. """
            for child in multiprocessing.active_children():
                self.logger.error("Waited %s seconds to shut down %s, "
                                  "terminating" % (self.shutdown_timeout,
                                                   child.name))
                child.terminate()

        timer = threading.Timer(self.shutdown_timeout, term_children)
        timer.start()
        while len(multiprocessing.active_children()):
            self.logger.info("Waiting for %s child(ren): %s" %
                             (len(multiprocessing.active_children()),
                              [c.name
                               for c in multiprocessing.active_children()]))
            time.sleep(1)
        timer.cancel()
        self.logger.info("All children shut down")

        while len(threading.enumerate()) > 1:
            threads = [t for t in threading.enumerate()
                       if t != threading.current_thread()]
            self.logger.info("Waiting for %s thread(s): %s" %
                             (len(threads), [t.name for t in threads]))
            time.sleep(1)
        self.logger.info("Shutdown complete")
Пример #3
0
    def shutdown(self):
        BuiltinCore.shutdown(self)
        self.logger.info("Closing RPC command queues")
        self.rpc_q.close()

        def term_children():
            """ Terminate all remaining multiprocessing children. """
            for child in multiprocessing.active_children():
                self.logger.error("Waited %s seconds to shut down %s, "
                                  "terminating" %
                                  (self.shutdown_timeout, child.name))
                child.terminate()

        timer = threading.Timer(self.shutdown_timeout, term_children)
        timer.start()
        while len(multiprocessing.active_children()):
            self.logger.info(
                "Waiting for %s child(ren): %s" %
                (len(multiprocessing.active_children()),
                 [c.name for c in multiprocessing.active_children()]))
            time.sleep(1)
        timer.cancel()
        self.logger.info("All children shut down")

        while len(threading.enumerate()) > 1:
            threads = [
                t for t in threading.enumerate()
                if t != threading.current_thread()
            ]
            self.logger.info("Waiting for %s thread(s): %s" %
                             (len(threads), [t.name for t in threads]))
            time.sleep(1)
        self.logger.info("Shutdown complete")
Пример #4
0
    def __init__(self):
        BuiltinCore.__init__(self)

        #: A dict of child name -> one end of the
        #: :class:`multiprocessing.Pipe` object used to communicate
        #: with that child.  (The child is given the other end of the
        #: Pipe.)
        self.pipes = dict()

        #: A queue that keeps track of which children are available to
        #: render a configuration.  A child is popped from the queue
        #: when it starts to render a config, then it's pushed back on
        #: when it's done.  This lets us use a blocking call to
        #: :func:`Queue.Queue.get` when waiting for an available
        #: child.
        self.available_children = \
            Queue(maxsize=Bcfg2.Options.setup.core_children)

        #: The flag that indicates when to stop child threads and
        #: processes
        self.terminate = DualEvent(threading_event=self.terminate)

        #: A :class:`Bcfg2.Server.MultiprocessingCore.RPCQueue` object
        #: used to send or publish commands to children.
        self.rpc_q = RPCQueue()

        #: A list of children that will be cycled through
        self._all_children = []

        #: An iterator that each child will be taken from in sequence,
        #: to provide a round-robin distribution of render requests
        self.children = None
Пример #5
0
    def _run(self):
        for cnum in range(Bcfg2.Options.setup.core_children):
            name = "Child-%s" % cnum

            self.logger.debug("Starting child %s" % name)
            child_q = self.rpc_q.add_subscriber(name)
            childcore = ChildCore(name, child_q, self.terminate)
            child = multiprocessing.Process(target=childcore.run, name=name)
            child.start()
            self.logger.debug("Child %s started with PID %s" % (name,
                                                                child.pid))
            self._all_children.append(name)
        self.logger.debug("Started %s children: %s" % (len(self._all_children),
                                                       self._all_children))
        self.children = cycle(self._all_children)
        return BuiltinCore._run(self)
Пример #6
0
    def _get_rmi(self):
        child_rmi = dict()
        for pname, pinst in self._get_rmi_objects().items():
            for crmi in pinst.__child_rmi__:
                if isinstance(crmi, tuple):
                    parentname, childname = crmi
                else:
                    parentname = childname = crmi
                child_rmi["%s.%s" % (pname, parentname)] = \
                    "%s.%s" % (pname, childname)

        rmi = BuiltinCore._get_rmi(self)
        for method in rmi.keys():
            if method in child_rmi:
                rmi[method] = self._child_rmi_wrapper(method, rmi[method],
                                                      child_rmi[method])
        return rmi
Пример #7
0
    def _run(self):
        for cnum in range(Bcfg2.Options.setup.core_children):
            name = "Child-%s" % cnum

            self.logger.debug("Starting child %s" % name)
            child_q = self.rpc_q.add_subscriber(name)
            childcore = ChildCore(name, child_q, self.terminate)
            child = multiprocessing.Process(target=childcore.run, name=name)
            child.start()
            self.logger.debug("Child %s started with PID %s" %
                              (name, child.pid))
            self._all_children.append(name)
        self.logger.debug("Started %s children: %s" %
                          (len(self._all_children), self._all_children))
        self.children = cycle(self._all_children)
        Bcfg2.Server.Cache.add_expire_hook(self.cache_dispatch)
        return BuiltinCore._run(self)
Пример #8
0
    def _get_rmi(self):
        child_rmi = dict()
        for pname, pinst in self._get_rmi_objects().items():
            for crmi in pinst.__child_rmi__:
                if isinstance(crmi, tuple):
                    parentname, childname = crmi
                else:
                    parentname = childname = crmi
                child_rmi["%s.%s" % (pname, parentname)] = \
                    "%s.%s" % (pname, childname)

        rmi = BuiltinCore._get_rmi(self)
        for method in rmi.keys():
            if method in child_rmi:
                rmi[method] = self._child_rmi_wrapper(method,
                                                      rmi[method],
                                                      child_rmi[method])
        return rmi
Пример #9
0
    def get_statistics(self, address):
        stats = dict()

        def _aggregate_statistics(newstats, prefix=None):
            """ Aggregate a set of statistics from a child or parent
            server core.  This adds the statistics to the overall
            statistics dict (optionally prepending a prefix, such as
            "Child-1", to uniquely identify this set of statistics),
            and aggregates it with the set of running totals that are
            kept from all cores. """
            for statname, vals in newstats.items():
                if statname.startswith("ChildCore:"):
                    statname = statname[5:]
                if prefix:
                    prettyname = "%s:%s" % (prefix, statname)
                else:
                    prettyname = statname
                stats[prettyname] = vals
                totalname = "Total:%s" % statname
                if totalname not in stats:
                    stats[totalname] = vals
                else:
                    newmin = min(stats[totalname][0], vals[0])
                    newmax = max(stats[totalname][1], vals[1])
                    newcount = stats[totalname][3] + vals[3]
                    newmean = ((stats[totalname][2] * stats[totalname][3]) +
                               (vals[2] * vals[3])) / newcount
                    stats[totalname] = (newmin, newmax, newmean, newcount)

        stats = dict()
        for childname in self._all_children:
            _aggregate_statistics(self.rpc_q.rpc(childname,
                                                 "get_statistics",
                                                 args=[address]),
                                  prefix=childname)
        _aggregate_statistics(BuiltinCore.get_statistics(self, address))
        return stats
Пример #10
0
    def get_statistics(self, address):
        stats = dict()

        def _aggregate_statistics(newstats, prefix=None):
            """ Aggregate a set of statistics from a child or parent
            server core.  This adds the statistics to the overall
            statistics dict (optionally prepending a prefix, such as
            "Child-1", to uniquely identify this set of statistics),
            and aggregates it with the set of running totals that are
            kept from all cores. """
            for statname, vals in newstats.items():
                if statname.startswith("ChildCore:"):
                    statname = statname[5:]
                if prefix:
                    prettyname = "%s:%s" % (prefix, statname)
                else:
                    prettyname = statname
                stats[prettyname] = vals
                totalname = "Total:%s" % statname
                if totalname not in stats:
                    stats[totalname] = vals
                else:
                    newmin = min(stats[totalname][0], vals[0])
                    newmax = max(stats[totalname][1], vals[1])
                    newcount = stats[totalname][3] + vals[3]
                    newmean = ((stats[totalname][2] * stats[totalname][3]) +
                               (vals[2] * vals[3])) / newcount
                    stats[totalname] = (newmin, newmax, newmean, newcount)

        stats = dict()
        for childname in self._all_children:
            _aggregate_statistics(
                self.rpc_q.rpc(childname, "get_statistics", args=[address]),
                prefix=childname)
        _aggregate_statistics(BuiltinCore.get_statistics(self, address))
        return stats
Пример #11
0
 def set_debug(self, address, debug):
     self.rpc_q.set_debug(debug)
     self.rpc_q.publish("set_debug", args=[address, debug])
     return BuiltinCore.set_debug(self, address, debug)
Пример #12
0
 def set_debug(self, address, debug):
     self.rpc_q.set_debug(debug)
     self.rpc_q.publish("set_debug", args=[address, debug])
     return BuiltinCore.set_debug(self, address, debug)