def fetch_metrics(self):
    for index, metric_source in enumerate(self.metric_sources):
      # Randomize the start time of each metric source.
      # Because StatusUpdater will always update cluster status every 'self.collector_config.period',
      # here, we use 'self.collector_config.period - 2' to give each task at least 2 seconds to
      # download page and update its status into database before StatusUpdater starting to update cluster
      # status based on each task's status
      wait_time = random.uniform(0, self.collector_config.period - 2)
      # store the metric_source id for one task and just return the metric_source id to
      # the output queue when the subprocesses complete the task.
      metric_source.task.metric_source_id = index
      # store a redundant attribute 'need_analyze' for task
      metric_source.task.need_analyze = metric_source.need_analyze
      logger.info("%r waiting %f seconds for %s..." ,
        metric_source.task, wait_time, metric_source.url)
      reactor.callLater(wait_time, metric_source.fetch_metrics, self.input_queue)
  
    # schedule next fetch for metrics updating
    reactor.callLater(self.collector_config.period - 2, self.schedule_next_rolling)

    # call status updater task after fetching metrics
    status_updater = StatusUpdater(self.collector_config)
    reactor.callLater(self.collector_config.period + 1,
      status_updater.produce_status_update_task, self.input_queue)

    region_operation_aggregator = RegionOperationMetricAggregator(
      self.collector_config)
    # we start to aggregate region operation metric after one period
    reactor.callLater(self.collector_config.period + 1,
      region_operation_aggregator.produce_aggregate_task, self.input_queue)

    reactor.run()
dataset/ETHPy150Open XiaoMi/minos/owl/collector/management/commands/collect.py/Command.fetch_metrics/original