def execute_operation(self, operation_id, triggered_time, expect_start_time, window_time, **kwargs): if operation_id in self._operation_thread_map: LOG.warning( _LW("Execute operation(%s), " "the previous one has not been finished"), operation_id) return num = CONF.operationengine.max_concurrent_operations if num and len(self._operation_thread_map) >= num: LOG.warning( _LW("The amount of concurrent running operations " "exceeds %d"), num) return self._operation_thread_map[operation_id] = None end_time_for_run = expect_start_time + timedelta(seconds=window_time) ret = self._update_operation_state( operation_id, { 'state': constants.OPERATION_STATE_TRIGGERED, 'end_time_for_run': end_time_for_run }) if not ret: self._operation_thread_map.pop(operation_id, None) return if operation_id not in self._operation_thread_map: # This function is invoked by trigger which may runs in the # green thread. So if operation_id is not exist, it may be # canceled by 'cancel_operation' during the call to DB in # the codes above. LOG.warning(_LW("Operation(%s) is not exist after call to DB"), operation_id) return param = { 'operation_id': operation_id, 'triggered_time': triggered_time, 'expect_start_time': expect_start_time, 'window_time': window_time, 'run_type': constants.OPERATION_RUN_TYPE_EXECUTE } try: self._create_thread(self._run_operation, operation_id, param) except Exception: self._operation_thread_map.pop(operation_id, None) LOG.exception( _LE("Execute operation (%s), " "and create green thread failed"), operation_id)
def execute_operation(self, operation_id, triggered_time, expect_start_time, window_time, **kwargs): if self._check_operation(operation_id, self._CHECK_ITEMS.values()): LOG.warning(_LW("Execute operation(%s), it can't be executed"), operation_id) return end_time_for_run = expect_start_time + timedelta(seconds=window_time) ret = self._update_operation_state( operation_id, { 'state': constants.OPERATION_STATE_TRIGGERED, 'end_time_for_run': end_time_for_run }) if not ret: return param = { 'operation_id': operation_id, 'triggered_time': triggered_time, 'expect_start_time': expect_start_time, 'window_time': window_time, 'run_type': constants.OPERATION_RUN_TYPE_EXECUTE } self._execute_operation(operation_id, self._run_operation, param)
def kill(self): """Destroy the service object in the datastore.""" self.stop() try: db.service_destroy(context.get_admin_context(), self.service_id) except exception.NotFound: LOG.warning(_LW('Service killed that has no database entry'))
def _on_gt_done(self, gt, *args, **kwargs): op_id = args[0] try: del self._operation_thread_map[op_id] except Exception: LOG.warning( _LW("Unknown operation id(%s) received, " "when the green thread exit"), op_id)
def _get_karbor_auth_plugin(self, trust_id=None): auth_plugin = loading.load_auth_from_conf_options( CONF, TRUSTEE_CONF_GROUP, trust_id=trust_id) if not auth_plugin: LOG.warning(_LW('Please add the trustee credentials you ' 'need to the %s section of your karbor.conf ' 'file.') % TRUSTEE_CONF_GROUP) raise exception.AuthorizationFailure(obj=TRUSTEE_CONF_GROUP) return auth_plugin
def execute_operation(self, operation_id, triggered_time, expect_start_time, window_time, **kwargs): if operation_id in self._operation_thread_map: LOG.warning(_LW("Execute operation(%s), " "the previous one has not been finished"), operation_id) return num = CONF.operationengine.max_concurrent_operations if num and len(self._operation_thread_map) >= num: LOG.warning(_LW("The amount of concurrent running operations " "exceeds %d"), num) return self._operation_thread_map[operation_id] = None end_time_for_run = expect_start_time + timedelta(seconds=window_time) ret = self._update_operation_state( operation_id, {"state": constants.OPERATION_STATE_TRIGGERED, "end_time_for_run": end_time_for_run} ) if not ret: self._operation_thread_map.pop(operation_id, None) return if operation_id not in self._operation_thread_map: # This function is invoked by trigger which may runs in the # green thread. So if operation_id is not exist, it may be # canceled by 'cancel_operation' during the call to DB in # the codes above. LOG.warning(_LW("Operation(%s) is not exist after call to DB"), operation_id) return param = { "operation_id": operation_id, "triggered_time": triggered_time, "expect_start_time": expect_start_time, "window_time": window_time, "run_type": constants.OPERATION_RUN_TYPE_EXECUTE, } try: self._create_thread(self._run_operation, operation_id, param) except Exception: self._operation_thread_map.pop(operation_id, None) LOG.exception(_LE("Execute operation (%s), " "and create green thread failed"), operation_id)
def _get_karbor_auth_plugin(self, trust_id=None): auth_plugin = loading.load_auth_from_conf_options(CONF, TRUSTEE_CONF_GROUP, trust_id=trust_id) if not auth_plugin: LOG.warning( _LW('Please add the trustee credentials you ' 'need to the %s section of your karbor.conf ' 'file.') % TRUSTEE_CONF_GROUP) raise exception.AuthorizationFailure(obj=TRUSTEE_CONF_GROUP) return auth_plugin
def basic_config_check(self): """Perform basic config checks before starting service.""" # Make sure report interval is less than service down time if self.report_interval: if CONF.service_down_time <= self.report_interval: new_down_time = int(self.report_interval * 2.5) LOG.warning( _LW("Report interval must be less than service down " "time. Current config service_down_time: " "%(service_down_time)s, report_interval for this: " "service is: %(report_interval)s. Setting global " "service_down_time to: %(new_down_time)s"), {'service_down_time': CONF.service_down_time, 'report_interval': self.report_interval, 'new_down_time': new_down_time}) CONF.set_override('service_down_time', new_down_time, enforce_type=True)
def basic_config_check(self): """Perform basic config checks before starting service.""" # Make sure report interval is less than service down time if self.report_interval: if CONF.service_down_time <= self.report_interval: new_down_time = int(self.report_interval * 2.5) LOG.warning( _LW("Report interval must be less than service down " "time. Current config service_down_time: " "%(service_down_time)s, report_interval for this: " "service is: %(report_interval)s. Setting global " "service_down_time to: %(new_down_time)s"), { 'service_down_time': CONF.service_down_time, 'report_interval': self.report_interval, 'new_down_time': new_down_time }) CONF.set_override('service_down_time', new_down_time, enforce_type=True)
def execute_operation(self, operation_id, triggered_time, expect_start_time, window_time, **kwargs): if self._check_operation(operation_id, self._CHECK_ITEMS.values()): LOG.warning(_LW("Execute operation(%s), it can't be executed"), operation_id) return end_time_for_run = expect_start_time + timedelta(seconds=window_time) ret = self._update_operation_state( operation_id, {'state': constants.OPERATION_STATE_TRIGGERED, 'end_time_for_run': end_time_for_run}) if not ret: return param = { 'operation_id': operation_id, 'triggered_time': triggered_time, 'expect_start_time': expect_start_time, 'window_time': window_time, 'run_type': constants.OPERATION_RUN_TYPE_EXECUTE } self._execute_operation(operation_id, self._run_operation, param)
def _trigger_operations(self, expect_run_time, trigger_property, timer): """Trigger operations once returns: wait time for next run """ # Just for robustness, actually expect_run_time always <= now # but, if the scheduling of eventlet is not accurate, then we # can do some adjustments. entry_time = datetime.utcnow() if entry_time < expect_run_time and ( int(timeutils.delta_seconds(entry_time, expect_run_time)) > 0): return expect_run_time # The self._executor.execute_operation may have I/O operation. # If it is, this green thread will be switched out during looping # operation_ids. In order to avoid changing self._operation_ids # during the green thread is switched out, copy self._operation_ids # as the iterative object. operation_ids = self._operation_ids.copy() sent_ops = set() window = trigger_property.get("window") end_time = expect_run_time + timedelta(seconds=window) for operation_id in operation_ids: if operation_id not in self._operation_ids: # Maybe, when traversing this operation_id, it has been # removed by self.unregister_operation LOG.warn(_LW("Execuete operation %s which is not exist, " "ignore it"), operation_id) continue now = datetime.utcnow() if now >= end_time: LOG.error(_LE("Can not trigger operations to run. " "Because it is out of window time. " "now=%(now)s, end time=%(end_time)s, " "expect run time=%(expect)s, " "wating operations=%(ops)s"), {'now': now, 'end_time': end_time, 'expect': expect_run_time, 'ops': operation_ids - sent_ops}) break try: self._executor.execute_operation( operation_id, now, expect_run_time, window) except Exception: LOG.exception(_LE("Submit operation to executor " "failed, operation id=%s"), operation_id) sent_ops.add(operation_id) next_time = self._compute_next_run_time( expect_run_time, trigger_property['end_time'], timer) now = datetime.utcnow() if next_time and next_time <= now: LOG.error(_LE("Next run time:%(next_time)s <= now:%(now)s. Maybe " "the entry time=%(entry)s is too late, even exceeds " "the end time of window=%(end)s, or it was blocked " "where sending the operation to executor."), {'next_time': next_time, 'now': now, 'entry': entry_time, 'end': end_time}) return next_time
def _on_gt_done(self, gt, *args, **kwargs): op_id = args[0] try: del self._operation_thread_map[op_id] except Exception: LOG.warning(_LW("Unknown operation id(%s) received, " "when the green thread exit"), op_id)
def _trigger_operations(self, expect_run_time, trigger_property, timer): """Trigger operations once returns: wait time for next run """ # Just for robustness, actually expect_run_time always <= now # but, if the scheduling of eventlet is not accurate, then we # can do some adjustments. entry_time = datetime.utcnow() if entry_time < expect_run_time and (int( timeutils.delta_seconds(entry_time, expect_run_time)) > 0): return expect_run_time # The self._executor.execute_operation may have I/O operation. # If it is, this green thread will be switched out during looping # operation_ids. In order to avoid changing self._operation_ids # during the green thread is switched out, copy self._operation_ids # as the iterative object. operation_ids = self._operation_ids.copy() sent_ops = set() window = trigger_property.get("window") end_time = expect_run_time + timedelta(seconds=window) for operation_id in operation_ids: if operation_id not in self._operation_ids: # Maybe, when traversing this operation_id, it has been # removed by self.unregister_operation LOG.warn( _LW("Execuete operation %s which is not exist, " "ignore it"), operation_id) continue now = datetime.utcnow() if now >= end_time: LOG.error( _LE("Can not trigger operations to run. " "Because it is out of window time. " "now=%(now)s, end time=%(end_time)s, " "expect run time=%(expect)s, " "wating operations=%(ops)s"), { 'now': now, 'end_time': end_time, 'expect': expect_run_time, 'ops': operation_ids - sent_ops }) break try: self._executor.execute_operation(operation_id, now, expect_run_time, window) except Exception: LOG.exception( _LE("Submit operation to executor " "failed, operation id=%s"), operation_id) sent_ops.add(operation_id) next_time = self._compute_next_run_time(expect_run_time, trigger_property['end_time'], timer) now = datetime.utcnow() if next_time and next_time <= now: LOG.error( _LE("Next run time:%(next_time)s <= now:%(now)s. Maybe " "the entry time=%(entry)s is too late, even exceeds " "the end time of window=%(end)s, or it was blocked " "where sending the operation to executor."), { 'next_time': next_time, 'now': now, 'entry': entry_time, 'end': end_time }) return next_time