def _validate_and_update(self, attribute): """Validates the current values on this WorkUnit and propegates updates. This method validates the current WorkUnit and performs any updates that occur as side-effects, such as updating the start and end time. This method also calls change listeners and propagates change calls to parent WorkUnits. Args: attribute: A string value corresponding to the name of the attribute that was updated. Raises: ValueError: A ValueError is raised if any of the current values are in an invalid state. For instance, if the completed count is greater that the total count. """ if (not self._total == None and not self._complete == None and self._complete > self._total): raise ValueError( 'Complete tasks cannot be more than the total tasks.') if not self.start_time: self.start_time = util.timer() if self.total == self.complete and not self.total == None: self.end_time = util.timer() self._waiting = False for listener in self.listeners: listener.update(self, attribute, getattr(self, attribute)) if self.parent: self.parent._validate_and_update(attribute)
def _validate_and_update(self, attribute): """Validates the current values on this WorkUnit and propegates updates. This method validates the current WorkUnit and performs any updates that occur as side-effects, such as updating the start and end time. This method also calls change listeners and propagates change calls to parent WorkUnits. Args: attribute: A string value corresponding to the name of the attribute that was updated. Raises: ValueError: A ValueError is raised if any of the current values are in an invalid state. For instance, if the completed count is greater that the total count. """ if (not self._total == None and not self._complete == None and self._complete > self._total): raise ValueError('Complete tasks cannot be more than the total tasks.') if not self.start_time: self.start_time = util.timer() if self.total == self.complete and not self.total == None: self.end_time = util.timer() self._waiting = False for listener in self.listeners: listener.update(self, attribute, getattr(self, attribute)) if self.parent: self.parent._validate_and_update(attribute)
def _succeed(self): """Signals that rule execution has completed successfully. This will set all state and issue the callback on the deferred. """ self.status = Status.SUCCEEDED self.end_time = util.timer() self.deferred.callback()
def begin(self): """Begins asynchronous rule execution. Custom RuleContext implementations should override this method to perform their behavior (spawning tasks/etc). When the returned Deferred is called back the rule context should be completed, with all_output_files properly set. The default implementation ends immediately, passing all input files through as output. Returns: A Deferred that can will be called back when the rule has completed. """ self.status = Status.RUNNING self.start_time = util.timer() # TODO(benvanik): real logging of rule processing # This makes the path relative and strips BUILD: (which may be wrong, w/e) rel_path = os.path.relpath(self.rule.path, self.build_env.root_path) rel_path = util.strip_implicit_build_name(rel_path) print '... %20s ~ %s' % (self.rule.rule_name, rel_path) # Compute file delta # Note that this could be done async (somehow) self.file_delta = self.build_context.cache.compute_delta( self.rule.path, 'src', self.src_paths) return self.deferred
def cascade_failure(self): """Instantly fails a rule, signaling that a rule prior to it has failed and it should not be run. Use this if a call to check_predecessor_failures returns True to properly set a rule context up for cascading failures. After calling this begin should not be called. Returns: A Deferred that has had its errback called. """ # TODO(benvanik): special CascadingError exception self.start_time = util.timer() self._fail() return self.deferred
def log_error(self, message, name=None): """Logs a message at ERROR log level. ERROR log level is recorded on LogSources with any verbosity level. Args: message: A string message to be logged. name: A string name representing the source of the message. Defaults to none. How this is used is up to the LogSource. """ if self._should_log(enums.LogLevel.ERROR): message = '[%s] %s' % (enums.log_level_to_string( enums.LogLevel.ERROR), message) self._log_internal( (enums.LogLevel.ERROR, util.timer(), name, message))
def log_info(self, message, name=None): """Logs a message at INFO log level. INFO log level is recorded on LogSources with VERBOSE or NORMAL verbosity. Args: message: A string message to be logged. name: A string name representing the source of the message. Defaults to none. How this is used is up to the LogSource. """ if self._should_log(enums.LogLevel.INFO): message = '[%s] %s' % (enums.log_level_to_string( enums.LogLevel.INFO), message) self._log_internal( (enums.LogLevel.INFO, util.timer(), name, message))
def log_error(self, message, name=None): """Logs a message at ERROR log level. ERROR log level is recorded on LogSources with any verbosity level. Args: message: A string message to be logged. name: A string name representing the source of the message. Defaults to none. How this is used is up to the LogSource. """ if self._should_log(enums.LogLevel.ERROR): message = '[%s] %s' % ( enums.log_level_to_string(enums.LogLevel.ERROR), message) self._log_internal( (enums.LogLevel.ERROR, util.timer(), name, message))
def log_info(self, message, name=None): """Logs a message at INFO log level. INFO log level is recorded on LogSources with VERBOSE or NORMAL verbosity. Args: message: A string message to be logged. name: A string name representing the source of the message. Defaults to none. How this is used is up to the LogSource. """ if self._should_log(enums.LogLevel.INFO): message = '[%s] %s' % ( enums.log_level_to_string(enums.LogLevel.INFO), message) self._log_internal( (enums.LogLevel.INFO, util.timer(), name, message))
def _fail(self, exception=None, *args, **kwargs): """Signals that rule execution has completed in failure. This will set all state and issue the errback on the deferred. If an exception is provided it will be set on the context and passed as the first argument to the deferred. Args: exception: The exception that resulted in the rule failure, if any. """ self.status = Status.FAILED self.end_time = util.timer() self.exception = exception # TODO(benvanik): real logging of rule failure print '!! failed %s' % (self.rule) if exception: self.deferred.errback(exception=exception) else: self.deferred.errback()