def __init__( self, interval: Optional[DurationLiteral] = 60, instant_run: bool = False, **kwargs: Any ): super().__init__(**kwargs) self._assert_polling_compat() if interval is None: # No scheduled execution. Use endpoint `/trigger` of api to execute. self._poll_interval = None self.interval = None self.is_cron = False else: try: # Literals such as 60s, 1m, 1h, ... self._poll_interval = parse_duration_literal(interval) self.interval = interval self.is_cron = False except TypeError: # ... or a cron-like expression is valid from cronex import CronExpression # type: ignore self._cron_interval = CronExpression(interval) self.interval = self._cron_interval self.is_cron = True self._is_running = False self._scheduler: Optional[Scheduler] = None self._instant_run = try_parse_bool(instant_run, False)
def handle(self, *args, **options): now = datetime.now() lock_time = now - settings.FSCAN_TDELTA['max'] orphan_proc = Scan.objects.filter( status=settings.SCAN_STATUS['in_process'], last_updated__lte=lock_time) for obj in orphan_proc: obj.unlock_task('find_scans call unlock task') for scan_task in ScanTask.objects.filter( status=settings.TASK_STATUS['free']): min_time_allowed = now - settings.FSCAN_TDELTA['max'] # start at fixed time if scan_task.start: now_delta = now - scan_task.start if (now_delta < settings.FSCAN_TDELTA['max'] and now_delta > settings.FSCAN_TDELTA['min']): if not Scan.objects.filter(scan_task=scan_task.id, finish__gte=min_time_allowed): logger.info('Found waiting time scan: %s' % scan_task.target) scan_task.run() # cron-schedule start if scan_task.cron: job = CronExpression(smart_str(scan_task.cron)) if job.check_trigger( (now.year, now.month, now.day, now.hour, now.minute)): if not Scan.objects.filter(scan_task=scan_task.id, finish__gte=min_time_allowed): logger.info('Found waiting cron scan: %s' % scan_task.target) scan_task.run()
def __init__(self, method, cron_expression, custom_messages = {}): """ Constructor @Params method : Method to be called when the timer is triggered minutes_between_posts : Time between calls of the method in minutes custom_messages : Custom log messages for console """ self._messages = { "triggering": "Triggering", "starting": "Starting", "syncing": "Syncing", "exiting": "Exiting" } # if only a few messages were chosen, overwrite those ones # rather than leave the others blank if custom_messages is not {}: for message in custom_messages: self._messages[message] = custom_messages[message] self._job = CronExpression(cron_expression + " Run timed method") self._method = method
def __init__(self, expressions, **kwargs): super().__init__(interval=60, instant_run=False, **kwargs) self.expressions = make_list(expressions) from cronex import CronExpression self.jobs = [ CronExpression(expression) for expression in self.expressions ]
def __init__(self, actor_config, cron="*/10 * * * *", payload="wishbone", field="@data"): Actor.__init__(self, actor_config) self.pool.createQueue("outbox") self.cron = CronExpression("%s wishbone" % self.kwargs.cron)
def should_run(schedule, date): cron = CronExpression(" ".join([ schedule.minute or "*", schedule.hour or "*", schedule.day or "*", schedule.month or "*", schedule.weekday or "*", ])) now = [date.year, date.month, date.day, date.hour, date.minute] return cron.check_trigger(now)
def validate_schedule_attribute(self, key, attribute): cron_expression = "{minute} {hour} {day} {month} {weekday}".format( minute=attribute if key == "minute" else "*", hour=attribute if key == "hour" else "*", day=attribute if key == "day" else "*", month=attribute if key == "month" else "*", weekday=attribute if key == "weekday" else "*", ) try: CronExpression(cron_expression) except ValueError: raise ValueError(f"The Schedule cannot accept the " f"value given in the {key} attribute") return attribute
def __init__(self, name, schedule, summary_regex=None, cron_expression=None): """ :param name: unique name for this job :type name: str :param schedule: the name of the schedule this job runs on :type schedule: str :param summary_regex: A regular expression to use for extracting a string from the job output for use in the summary table. If there is more than one match, the last one will be used. :type summary_regex: ``string`` or ``None`` :param cron_expression: A cron-like expression parsable by `cronex <https://github.com/ericpruitt/cronex>`_ specifying when the job should run. This has the effect of causing runs to skip this job unless the expression matches. It's recommended not to use any minute specifiers and not to use any hour specifiers if the total runtime of all jobs is more than an hour. :type cron_expression: str """ self._name = name self._schedule_name = schedule self._started = False self._finished = False self._exit_code = None self._output = None self._start_time = None self._finish_time = None self._summary_regex = summary_regex self._skip_reason = None self._cron_expression = None if cron_expression is not None: self._cron_expression = CronExpression(cron_expression) if not self._cron_expression.check_trigger( time.gmtime(time.time())[:5]): self._skip_reason = 'cronex: "%s"' % cron_expression
def __init__(self, expression): """ Args: expression (str) : classic cron expression string """ self.cronjob = CronExpression(expression)
def browse_config(config, cache): """Will browse all section of the config, fill cache and launch command when needed. """ commands.ip_neigh.cache_clear() processes = {} now = datetime.now() now = (now.year, now.month, now.day, now.hour, now.minute) excluded_sections = {config.default_section, const.KNOWN_MACHINES_SECTION} known_machines = utils.get_known_machines(config) for section in list(config.values()): if section.name in excluded_sections: continue if not section.getboolean('enabled'): logger.debug('section %r not enabled', section) continue cron = section.get('cron') if cron and not CronExpression(cron).check_trigger(now): logger.debug('section %r disabled for now', section) continue logger.debug('%r - processing section', section.name) cache.section_name = section.name device = section.get('device') neighbors = commands.ip_neigh(device=device) threshold = section.getint('threshold') if check_neighborhood(neighbors, section.get('filter_on_regex'), section.get('filter_out_regex'), section.get('filter_on_machines'), section.get('filter_out_machines'), section.get('exclude'), known_machines=known_machines): cmd = section.get('command_neighbor') result = 'neighbor' else: cmd = section.get('command_no_neighbor') result = 'no_neighbor' cache.cache_result(result, threshold) logger.info('%r - cache state: %r', section.name, cache.section) count = cache.get_result_count(result) if count != threshold: logger.info( "%r - cache count hasn't reached threshold yet " "(%d/%d)", section.name, count, threshold) continue if cache.last_command == cmd: logger.info('%r - command has already been run', section.name) continue cache.cache_command(cmd) if cmd: logger.warning('%r - launching: %r', section.name, cmd) processes[section.name] = commands.execute(cmd.split()) else: logger.info('%r - no command to launch', section.name) handle_processes(processes, config, cache)