コード例 #1
0
 def init_communication(self, ip, master_port, worker_port):
     self.ip = ip
     self.master_port = master_port
     self.worker_port = worker_port
     self.connection = WorkerConnection(self.ip, self.master_port, self.worker_port, self.name)
コード例 #2
0
class BaseWorker(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.working = False
        self.name = name
        self.simulation = False
        self.ip = MessageServerIP
        self.master_port = 0
        self.worker_port = 0
        self.input_config = None
        self.output_config = None
        self.outputs = {}
        self.inputs = {}
        self.schedule = None
        self.enabled = False
        self.active = False
        self.pausing_all_devices = False
        self.current_hold_time = timedelta(minutes=0)
        self.hold_timer = None
        self.hold_pause_timer = None
        self.pause_time = 0.0
        self.debug_timer = dt.now()
        self.session_detail_id = 0
        self.connection = None

    def __str__(self):
        return 'Worker - [name:{0}, type:{1}, out:{2}, in:{3}]'. \
            format(self.name, str(self.__class__.__name__), len(self.output_config), len(self.input_config))

    def init_communication(self, ip, master_port, worker_port):
        self.ip = ip
        self.master_port = master_port
        self.worker_port = worker_port
        self.connection = WorkerConnection(self.ip, self.master_port, self.worker_port, self.name)

    def create_device_threads(self):
        for i in self.input_config:
            device = core.utils.coreutils.load_device(i, self, self.simulation)
            if device is None:
                return False
            device.run_device()
            self.inputs[i.name] = device
        for o in self.output_config:
            device = core.utils.coreutils.load_device(o, self, self.simulation)
            if device is None:
                return False
            self.outputs[o.name] = device
            device.run_device()
        return True

    def start_all_devices(self):
        for i in self.inputs.values():
            self.inputs[i.name] = i.start_device()
        for o in self.outputs.values():
            self.outputs[o.name] = o.start_device()

    def is_any_device_enabled(self):
        for i in self.inputs.values():
            if i.enabled:
                return True
        for o in self.outputs.values():
            if o.enabled:
                return True
        return False

    def is_device_enabled(self, name):
        if len(self.inputs) != 0:
            if self.inputs[name].enabled:
                return True
        if len(self.outputs) != 0:
            if self.outputs[name].enabled:
                return True
        return False

    def pause_all_devices(self):
        if self.pausing_all_devices:
            return
        self.pausing_all_devices = True
        while self.is_any_device_enabled():
            log.debug('Trying to pause all passive devices...')
            for i in self.inputs.values():
                i.pause_device()
            for o in self.outputs.values():
                o.pause_device()
            time.sleep(1)
        log.debug('All passive devices paused')
        self.pausing_all_devices = False

    def resume_all_devices(self):
        while self.pausing_all_devices:
            time.sleep(1)
        log.debug('Resuming all passive devices...')
        for i in self.inputs.values():
            i.resume_device()
        for o in self.outputs.values():
            o.resume_device()
        log.debug('All passive devices resumed')
        self.pausing_all_devices = False

    def stop_all_devices(self):
        for i in self.inputs.values():
            i.stop_device()
        for o in self.outputs.values():
            o.stop_device()

    def work(self, data):
        pass

    def run(self):
        if not self.create_device_threads():
            log.error('Unable to load all devices, shutting down', True)
        self.info()
        self.listen()

    def listen(self):
        self.enabled = True
        self.on_start()
        while self.enabled:
            log.debug("worker is listening", True)
            data = self.connection.check()
            if data is not None:
                self.receive(data)
            time.sleep(0)
        log.debug('Shutting down worker {0}'.format(self), True)

    def stop(self):
        self.stop_all_devices()
        self.on_stop()
        self.enabled = False

    def send_to_master(self, data):
        #log.debug('Sending to master - ' + data + " " + str(self.ip) + ":" + str(self.port), True)
        self.connection.send(data)

    def send_measurement(self, worker_measurement):
        message = WorkerMeasurement.serialize_message(worker_measurement)
        if message is None:
            return
        self.send_to_master(message)

    @staticmethod
    def generate_worker_measurement(worker, device):
        return WorkerMeasurement(worker.session_detail_id, worker.name, device.name)

    def work_time(self):
        if self.current_hold_time is None:
            return None
        return self.current_hold_time + self.pause_time

    def finish_time(self):
        if self.hold_timer is None:
            return None
        return dt.now() - self.hold_timer

    def remaining_time(self):
        finish = self.finish_time()
        if finish is None:
            return None
        work = self.work_time()
        if work is None:
            return None
        if finish > work:
            return timedelta()
        return work - finish

    def remaining_time_info(self):
        remaining = self.remaining_time()
        if remaining is None:
            return '-n/a-'
        if remaining.microseconds >= 500000:
            remaining -= timedelta(seconds=-1, microseconds=remaining.microseconds)
        else:
            remaining -= timedelta(microseconds=remaining.microseconds)
        return str(remaining)

    def receive(self, body):
        if body in MessageFunctions and hasattr(self, body):
            getattr(self, body)()
            return
        for work_data in serializers.deserialize("json", body):
            session_detail = work_data.object
            self.session_detail_id = session_detail.id
            self.work(session_detail)
            break   # only the first instance

    def info(self):
        log.debug('{0} is sending info to master'.format(self.name), True)
        if self.on_info():
            worker_type = '{0}.{1}'.format(self.__module__, self.__class__.__name__)
            message = MessageReady + MessageSplit + self.name + MessageSplit + worker_type
            for input_device in self.inputs.keys():
                message += (MessageSplit + input_device)
            for output_device in self.outputs.keys():
                message += (MessageSplit + output_device)
            self.send_to_master(message)
        else:
            self.report_error('Info failed')

    def done(self):
        log.debug('{0} is sending done to master'.format(self.name), True)
        if self.on_done():
            message = "{0}{1}{2}{3}{4}".format(MessageDone, MessageSplit,
                                               self.name, MessageSplit,
                                               str(self.session_detail_id))
            self.send_to_master(message)
        else:
            self.report_error('Done failed')

    def pause(self):
        log.debug('{0} is sending paused to master'.format(self.name), True)
        if not self.on_pause():
            self.report_error('Pause failed')

    def resume(self):
        log.debug('{0} is sending resumed to master'.format(self.name), True)
        if not self.on_resume():
            self.report_error('Resume failed')

    def reset(self):
        log.debug('{0} is resetting'.format(self.name), True)
        if self.on_reset():
            self.info()
        else:
            self.report_error('Reset failed')

    def report_error(self, err):
        log.error('{0}: {1}'.format(self.name, err), True)

    def is_done(self):
        if self.hold_timer is None:
            return False
        finish = self.finish_time()
        if finish is None:
            return False
        work = self.work_time()
        if work is None:
            return False
        if finish >= work:
            return True
        log.debug('Time until work done: {0}'.format(work - finish), True)
        return False

    def finish(self):
        try:
            self.pause_all_devices()
            self.working = False
            self.done()
            self.session_detail_id = 0
            return True
        except Exception as e:
            log.error('Error in cleaning up after work: {0}'.format(e.args[0]), True)
            return False

    def on_start(self):
        log.debug('Starting {0}'.format(self), True)

    def on_info(self):
        log.debug('Info {0}'.format(self), True)
        return True

    def on_done(self):
        log.debug('Done {0}'.format(self), True)
        return True

    def on_pause(self):
        log.debug('Pause {0}'.format(self), True)
        self.pause_all_devices()
        self.hold_pause_timer = dt.now()
        return True

    def on_resume(self):
        log.debug('Resume {0}'.format(self), True)
        self.pause_time += (dt.now() - self.hold_pause_timer)
        self.resume_all_devices()
        return True

    def on_reset(self):
        self.pause_all_devices()
        return True

    def on_stop(self):
        self.stop_all_devices()
        return True