示例#1
0
class ChildProcess(object):
    """
    Wraps a multiprocess.Process instance, providing a Pipe and a Queue for
    communication between the SentinelDaemon and the ChildProcess.
    """
    def __init__(self, config, system, settings):
        """
        :type config: xml.etree.ElementTree.Element
        :type system: zoom.common.types.PlatformType
        """
        self._log = logging.getLogger('sent.child')
        self.parent_conn, self.child_conn = Pipe()
        self._action_queue = UniqueQueue()

        self.name = verify_attribute(config, 'id')
        self._application_type = verify_attribute(config, 'type')
        self._config = config
        self._system = system  # Linux or Windows
        self._settings = settings
        self._process = self._create_process()

    def add_work(self, work, immediate=False):
        """
        :type work: zoom.agent.entities.task.Task
        """
        added = self._action_queue.append_unique(work, sender=str(self),
                                                 first=immediate)
        # Here we are assuming that the work submitted is already in the queue.
        # In this case, we still need to alert the TaskManager that the work
        # was submitted (even if it was already there)
        if not added:
            self.child_conn.send('OK')

    def stop(self):
        """
        Stops the Process/Thread
        """ 
        try:
            self._log.info('Terminating {0} child process'.format(self.name))

            self.add_work(Task('terminate', block=True), immediate=True)
        except Exception as e:
            self._log.warning('Exception with stopping {0} child process: {1}'
                              .format(self.name, e))

    def join(self):
        """
        Block until underlying process completes.
        """
        self._process.join()
        self._log.info('{0} stopped.'.format(self))

    def _create_process(self):
        """
        :rtype: threading.Thread
        """
        self._log.debug('Starting worker process for %s' % self.name)
        
        if self._application_type == ApplicationType.APPLICATION:
            s = Application(self._config, self._settings, self.child_conn,
                            self._action_queue, self._system,
                            self._application_type)
        elif self._application_type == ApplicationType.JOB:
            s = Job(self._config, self._settings, self.child_conn,
                    self._action_queue, self._system, self._application_type)
            
        t = Thread(target=s.run, name=self.name)
        t.daemon = True
        t.start()
        return t
    
    def __str__(self):
        return 'ChildProcess(name={0}, type={1})'.format(self.name,
                                                         self._application_type)
示例#2
0
class ChildProcess(object):
    """
    Wraps a threading.Thread, providing a Queue for communication between
    the SentinelDaemon and the ChildProcess.
    """
    def __init__(self, config, system, settings):
        """
        :type config: xml.etree.ElementTree.Element
        :type system: zoom.common.types.PlatformType
        :type settings: dict
        """
        self._log = logging.getLogger('sent.child')
        self._action_queue = UniqueQueue()
        self._cancel_flag = ThreadSafeObject(False)

        self.name = verify_attribute(config, 'id')
        self._application_type = verify_attribute(config, 'type')
        self._config = config
        self._system = system  # Linux or Windows
        self._settings = settings
        self._process = self._create_process()

    def add_work(self, work, immediate=False):
        """
        :type work: zoom.agent.task.task.Task
        :type immediate: bool
        :rtype: bool
        """
        return self._action_queue.append_unique(work,
                                                sender=str(self),
                                                first=immediate)

    def cancel_current_task(self):
        """
        Set the cancel flag that is used in the process client.
        """
        # this seems like a hack. There must be a better way of cancelling while
        #   still allowing the agent to report up/down status
        DONT_REMOVE = ('register', 'unregister')
        self._log.info('Setting Cancel Flag and clearing queue.')
        self._cancel_flag.set_value(True)
        for i in list(self._action_queue):
            if i.name not in DONT_REMOVE:
                self._action_queue.remove(i)
                self._log.info('Removing task {0}'.format(i))

    def stop(self):
        """
        Stops the Process/Thread
        """
        try:
            self._log.info('Terminating {0} child process'.format(self.name))
            self.cancel_current_task()
            self.add_work(Task('terminate', block=True), immediate=True)
        except Exception as e:
            self._log.warning(
                'Exception with stopping {0} child process: {1}'.format(
                    self.name, e))

    def join(self):
        """
        Block until underlying process completes.
        """
        self._process.join()
        self._log.info('{0} stopped.'.format(self))

    def _create_process(self):
        """
        :rtype: threading.Thread
        """
        self._log.debug('Starting worker process for %s' % self.name)

        if self._application_type == ApplicationType.APPLICATION:
            s = Application(self._config, self._settings, self._action_queue,
                            self._system, self._application_type,
                            self._cancel_flag)
        elif self._application_type == ApplicationType.JOB:
            s = Job(self._config, self._settings, self._action_queue,
                    self._system, self._application_type, self._cancel_flag)

        t = Thread(target=s.run, name=self.name)
        t.daemon = True
        t.start()
        return t

    def __str__(self):
        return 'ChildProcess(name={0}, type={1})'.format(
            self.name, self._application_type)
示例#3
0
class ChildProcess(object):
    """
    Wraps a threading.Thread, providing a Queue for communication between
    the SentinelDaemon and the ChildProcess.
    """

    def __init__(self, config, system, settings):
        """
        :type config: xml.etree.ElementTree.Element
        :type system: zoom.common.types.PlatformType
        :type settings: dict
        """
        self._log = logging.getLogger("sent.child")
        self._action_queue = UniqueQueue()
        self._cancel_flag = ThreadSafeObject(False)

        self.name = verify_attribute(config, "id")
        self._application_type = verify_attribute(config, "type")
        self._config = config
        self._system = system  # Linux or Windows
        self._settings = settings
        self._process = self._create_process()

    def add_work(self, work, immediate=False):
        """
        :type work: zoom.agent.task.task.Task
        :type immediate: bool
        :rtype: bool
        """
        return self._action_queue.append_unique(work, sender=str(self), first=immediate)

    def cancel_current_task(self):
        """
        Set the cancel flag that is used in the process client.
        """
        # this seems like a hack. There must be a better way of cancelling while
        #   still allowing the agent to report up/down status
        DONT_REMOVE = ("register", "unregister")
        self._log.info("Setting Cancel Flag and clearing queue.")
        self._cancel_flag.set_value(True)
        for i in list(self._action_queue):
            if i.name not in DONT_REMOVE:
                self._action_queue.remove(i)
                self._log.info("Removing task {0}".format(i))

    def stop(self):
        """
        Stops the Process/Thread
        """
        try:
            self._log.info("Terminating {0} child process".format(self.name))
            self.cancel_current_task()
            self.add_work(Task("terminate", block=True), immediate=True)
        except Exception as e:
            self._log.warning("Exception with stopping {0} child process: {1}".format(self.name, e))

    def join(self):
        """
        Block until underlying process completes.
        """
        self._process.join()
        self._log.info("{0} stopped.".format(self))

    def _create_process(self):
        """
        :rtype: threading.Thread
        """
        self._log.debug("Starting worker process for %s" % self.name)

        if self._application_type == ApplicationType.APPLICATION:
            s = Application(
                self._config,
                self._settings,
                self._action_queue,
                self._system,
                self._application_type,
                self._cancel_flag,
            )
        elif self._application_type == ApplicationType.JOB:
            s = Job(
                self._config,
                self._settings,
                self._action_queue,
                self._system,
                self._application_type,
                self._cancel_flag,
            )

        t = Thread(target=s.run, name=self.name)
        t.daemon = True
        t.start()
        return t

    def __str__(self):
        return "ChildProcess(name={0}, type={1})".format(self.name, self._application_type)